余额宝-国民基金的大规模服务化的技术创新之道_第1页
余额宝-国民基金的大规模服务化的技术创新之道_第2页
余额宝-国民基金的大规模服务化的技术创新之道_第3页
余额宝-国民基金的大规模服务化的技术创新之道_第4页
余额宝-国民基金的大规模服务化的技术创新之道_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 余额宝:国民基金的大规模服务化的技术创新之道 今年7月初我在ArchSummit大会上做了题为余额宝大规模服务化的技术创新的分享,反响还不错。现将PPT和讲稿整理出来,分享给大家。这次分享首先介绍的是余额宝的整体架构变迁历史;第二部分讲一讲我们是如何进行基金实时销售平台及大数据平台的服务化改造的;最后介绍“服务化”对我们运维及研发模式的影响及我们的应对策略。余额宝本质上是一支货币基金,它的背后是天弘的增利宝基金。由于和支付宝的关系,它既是理财产品,又是支付产品,理财和支付的双重属性,再加上互联网产品所特有的极简的用户体验,让余额宝一经推出,迅速成为了“爆款”,短短五年内获得了一个惊人的发展。

2、可以毫不夸张的说,余额宝的出现,开启了中国的全民理财时代!为了适应业务的爆炸式增长,5年来余额宝的技术架构做了4次大的变更,每次技术变更的背后,都承载了天弘技术团队对系统规模、可扩展性及升级成本的综合考量和平衡之道。余额宝上线之初,解决的是“从无到有”的问题。当时没有其它类似的互联网金融产品可以做参考,我们采用了传统的典型企业级金融架构。由于采用的是自建IDC机房的方式,我们用硬件负载均衡设备将交易请求接入进来,前端是由两台weblogic构成的小型的前置处理集群,请求被稍做处理之后,即被送到后端由金正的基金交易中间件构建的集群做业务处理,其中 KCXP 和 KCBP 是金证公司的消息中间件和

3、业务中间件,业务数据存储采用的是两台Oracle数据库服务器构建的一主一备的小集群,这个是线上库,同时,还有一个同样架构的历史库服务。硬件方面采用的都是小型机设备,数据备份则采用EMC的产品。这是典型的IOE架构,全套的商用软硬件配置,成本很高。架构体系虽然很多环节都采用了集群的方式,但更多的是使用主备模式,而不是负载均衡的分布式模式,因此系统的单点资源负载压力较大,尤其是数据库,基本上就是单库模式(另一个库是备库),扩展性较差。当时的系统容量设计上限是能支持千万级用户,传统基金销售模式是走代销机构的方式,投资基金用户也多以理财为目的。所以每天可能处理的帐户开户也就是几万到几十万的规模。由于余

4、额宝对接是支付宝,支付宝的用户规模达到千万级,这是设计产品时对需求的定位。按照预估,这个设计容量怎么都能扛个几年。结果,我们低估了余额宝的热度,上线短短10天左右,新开户数已经突破100W了,按这个速度,3个月左右数据库容量上线就要被突破。事实也确实如此,我们的客户量三个月就达到一千万,余额宝一期系统的生命周期只有三个月!所以一期系统甫一上线,团队就不得不开始考虑扩容,计划将容量扩充3050倍,计算规模也同步增加。如果还是采用一期系统的纯商用软硬件的模式进行横向扩展的话,成本要达到12个亿,这样的成本对于当时天弘这样一家小型基金公司而言,是不可负担之重!因此,在阿里的建议下,我们决定整体上云。

5、当时做出这个决定的压力还是非常大的,因为当时没有任何一家金融公司和基金公司这么玩,我们成了第一个吃螃蟹的人。但在巨大的成本压力之下,我们走出了这一步,这就是余额宝2.0!2.0的架构中用阿里云上的软负载均衡SLB替换了硬件负载均衡;用阿里云上的虚拟计算单元ECS替换小型机成为前置服务及中间件服务的服务器;用阿里云的web服务替换了前置服务器上的weblogic。最大的一个变化是数据库层面,原来的Oracle单库被替换成了阿里云上的一个50个节点的RDS集群,实际上就是进行了分库分表的拆分,经过测算,需要使用50组业务节点,但在拆分时,考虑到扩展性,并未简单地拆分成50份,而是根据用户帐号ID作

6、为分片主键将核心业务表拆分成1000份,然后每个节点处理20份数据(物理子表)。这样做的好处是将来如果系统遇到瓶颈,需要扩容时,不需要对拆分算法进行修改,而且数据平均迁移时只需要以库为级别进行,从而避免了拆表。上云后,不仅数据库总容量有了几十倍的提升,交易处理效率也从一期的120W笔/小时提升到了近2000W笔/小时;最大清算时间从之前的7个多小时降低到了不到2个小时;而总成本,才增加了不到1倍。所以,上云对我们系统整体效率的提升和成本的降低有非常明显的作用。余额宝2.0的架构稳定运行了近3年,中间经历了几次小的升级优化,有力支撑了这个过程中的各种业务创新,但也在支撑业务快速发展中埋下了一些“

7、坑”。2016年,我们决定对系统进行一次大升级。这次升级的主要基调就是“业务逻辑重构,优化清算流程”,这就是余额宝3.0!这一阶段的业务逻辑复杂度要远远高于3年前,因此3.0的架构中,计算单元比2.0有了明显的扩充。由于数据库前期预留的buffer比较大,并没有成为本阶段的瓶颈,依然维持了50个节点的规模。这次升级之后,总体计算能力有了较大幅度的提高。处理效率比起2.0的时候增长了2倍多,也支撑了2016年春节期间日交易4亿多笔的峰值。但是,清算时间比2.0时期有较大增长,这成了系统的一个“隐患”。2017年,为了配合支付宝拓宽线下支付场景,并将业务推广覆盖到三、四线城市,同时,也要解决清算时

8、间过长的隐患,我们规划了余额宝4.0的升级。这一阶段的系统规模已经很大了,如果还是按3.0的架构进行横向扩充的话,成本将呈线性增长。经过综合考量,决定在升级前,先优化单节点的处理性能,提高效率及负载后再扩容,以降低总体的升级成本。因此,这次升级首先将直销和代销业务合二为一,同一台计算单元既处理直销业务,也处理代销业务,提高了单点的处理效率。在此基础上,再进行扩容,将计算单元从340节点扩充到480节点,数据库扩容4倍。通过这两步优化及扩充动作,最终系统的容量及计算能力均有了48倍的提高,这套新的架构支撑我们平稳度过了2017年双十一及春节的交易高峰。看到这里,大家可能会有疑问:一般在系统服务化

9、改造中,服务是会被拆的越来越细,为什么我们反其道而行,反而对服务进行了整合?这是因为,余额宝发展到现在,业务模式已经比较成熟,通过细粒度的服务模态来保证可扩展性的需求已经不是那么强烈;另一方面,系统规模庞大,扩容的成本成为重点考虑因素;综合这两方面的考量,适当增加单点的复杂度,可以降低整体成本。目前,针对余额宝这单只基金已经建立起了一套完整的技术生态体系,它的核心是余额宝的产品、帐号、交易、清算等模块,在结合实时调用和文件交互两套接口的基础上,构建了电商大数据的分析体系及一系列辅助支撑系统。同时,余额宝系统和其它第三方系统也有大量的交互,包括支付宝、监管、直代销渠道等等。余额宝系统的建设直接锻

10、炼了天弘的技术团队,让我们明白了大型互联网应用是一个什么样的玩法,这也直接推动了天弘自有的基金直销平台的服务化改造。接下来,我将从基金实时交易平台及大数据平台的服务化改造这两方面来对此分别做详细介绍。在开始这块的内容之前,先简单的给大家介绍一下基金公司的业务。基金公司最主要的就是“买卖”基金,我们从直销和代销渠道把交易请求“接”进来,在我们的核心交易系统进行申购、认购、定投、赎回、转换等等操作,这个过程里,会涉及与支付渠道、银行等一系列的交付;同时,还有大量的清结算和TA清算,这个过程里,还要和银证监会、中登等一系列监管机构有数据上的交互。聚拢过来的巨量的资金会被统一管控、并投入到股市、债市、

11、货币市场等投资市场去赚钱收益。围绕这个业务还有相应的投研、基金产品管理、风控、客服等中后台的业务支持。以上,就是基金公司的日常业务模式。在天弘早期的基金销售系统的建设中,其实没有什么服务化的概念,当时的模式是有什么类型的业务,就针对这种业务单独开发一套独立的销售及清结算系统。由于业务量普遍不大,这些系统往往采用单体架构模式,不考虑横向扩展性。经过多年的发展和积累,内部多套直销及代销交易系统并存,系统间帐号没有打通,用户的资产数据无法统一,用户体验差;另一方面,各系统间功能重复的现象严重,不仅重复占用软硬件资源,版本的控制也很麻烦。这种状况甚至在我们整体迁移到云上之后还存在了很长的一段时间,所以

12、,所谓的“服务化”,并不是仅仅上云那么简单,它更多的还是涉及到架构思维的转变。痛定思痛之后,我们决定将这些系统中通用的能力,包括用户账户、交易、支付、资产、结算等抽取出来,以独立服务的形式对外提供通用服务。这样,原来的业务系统更多的充当了一个交易大厅的角色,可以做的更轻,扩展也就更容易了。用户的交易请求通过安全网关层被统一接入进来,我们目前使用了两套网关,一套是SLB,另外一套是移动网关。整套平台都是在阿里云及蚂蚁金融云的I层及P层能力基础之上构建的,我们在它们的基础之上还构建了相应的日志监控、服务治理、APM、运维管控等一系列能力。以上,就是我们目前实时交易平台的整体服务化的架构。数据分析也

13、是金融公司的一项重要工作,我们的大数据平台会从实时线上业务系统、清结算系统、运营活动、web及APP的用户埋点中采集各个维度的数据,并以ODS(操作型数据)汇总到数据仓库中,再根据预先定义的数据模型,抽取出相应的主数据。在此基础之上,基于用户、运营、资产、交易、风控等主题来构建多层次的数据集市。有了这个数据集市之后,我们就可以以服务的形式,在数据上做一层服务化的封装,在其上进行数据的应用。一类应用是数据的离线分析,包括留存分析、保有分析、营销分析等等;另一类应用是将这些重度汇总数据应用在实时业务之中,尤其是营销活动之中。我们在这些数据集市上,构建了一些高级运营活动,包括基于用户综合资产构建的理

14、财竞赛,如“弘运榜”、“年度账单”、“理财达人”等等;另外,我们还基于这些不同维度的数据,搞了一个衡量用户综合理财能力的指标体系,即“财商指数”。我们这套能力是基于阿里云上的大数据加工及分析能力来构建的,利用了阿里云的odps、DTS、QuickBI等一系列能力。在大数据平台的能力构建上,我们遵循如下模式:首先进行数据模型的规划;有了模型之后利用ETL进行数据的抽取、转换及清洗;接着再利用一系列的规则对数据质量进行监控;将格的数据共享出去,供其他方应用;另外,定期进行数据资产评估,基于评估结果不断的对模型进行优化调整。这样,就形成了对数据的闭环操作。在这里,要重点强调的是数据质量监控。对于离线

15、分析,数据的精度及实时性普遍要求不高;但对于二次使用的汇总数据,则有很高的精度要求和实时性要求,比如用于用户竞赛排行并有奖励的一些运营活动,由于每笔交易记录都与钱挂钩,用户对准确性很敏感,稍有不慎就会引发大规模的客诉,因此我们在自构建的规则引擎基础上,利用数百条预先定义的规则,对数据进行抽样或者全量的检测,一旦检测到异常,则会自动触发人工订正或者自动化数据订正的任务。我们目前使用的服务化的底层框架是蚂蚁金融云提供的SOFA-RPC,这是一套脱胎于阿里HSF的P2P直连模式的分布式服务框架。SOFA-RPC提供了相对简便的服务暴露及服务接入的方式。如上图所示,它可以基于Spring的扩展标签机制

16、,把一个Spring的bean实例以特定的协议暴露为远程服务,也可以以接口的形式把一个远程服务接入进来,同时,它还提供了链式过滤器的机制,对所有的服务调用请求进行一个串行式的处理,我们也可以通过它来实现一些自定义的服务管控策略,包括服务MOCK,线上数据采集等能力。单有分布式服务框架,还不足以保证服务化的平稳落地。企业服务化之路要走的顺畅,一定是要两条腿走路的,一条腿是分布式服务框架,另一条腿是服务治理,只有两条腿都健壮,路才能走的顺畅。阿里云结合它线上的资源编排和资源调度能力,为SOFA-RPC提供了相对完善的服务生命周期管理的能力,能够实现诸如服务上线、下线,扩容、缩容等操作。同时,蚂蚁还

17、提供了一个叫Guardian的组件,通过它可以实现对线上服务的熔断限流的自动保护机制,类似Netflix提供的Hystrix组件,大家有兴趣可以去了解一下。我所在的移动开发部门,采用了蚂蚁的移动开发平台MPaaS框架,MpaaS是类似OSGi的一套模块化的插件管理框架,APP应用需要的各种基础能力都可以以插件的形式集成进来,它提供的服务远程调用能力就是基于SOFA-RPC。我们看一下上面的这个图,MpaaS提供了统一的服务网关,可以实现对服务端的SOFA服务的远程调用能力;同时,它还提供了日志网关和消息网关,可以实现对APP上的埋点信息的采集服务及消息的推送服务。通过MPaaS这套框架,我们可

18、以相对方便的实现移动应用的开发工作。以上就是目前我们基金实时销售平台的整体服务化的一个状况,接下来,我们再介绍一下服务化对我们研发和运维的影响。服务化的本质就是一个“拆”字,原来的单体应用被拆成了大大小小的应用集群和服务集群,并被分散到网络的各个节点,由不同的团队负责,每个团队各管一段。在这个背景下,运维和研发都会遭遇一系列新的问题和挑战,包括故障的定界定位、调用关系的梳理、集群环境下的调试及分布式环境下的事务一致性的保障等等。接下来就来看看,我们是如何破解这些困局的。【只有更高效的收集线上服务的日志,才能更好的对服务进行监控和管控】传统的日志收集一般采用诸如log4j这类的日志组件进行日志的

19、落盘,再通过logstash或者flume这类的日志采集组件进行落盘日志的增量收集,通过这种方式进行日志采集存在大量的磁盘IO。对于线上服务器来说,最大的性能瓶颈就是磁盘IO,尤其是在高并发和高负载环境下,磁盘IO对系统性能的影响会被成倍放大。我们的测试显示,在整个系统负载被打满的前提下,日志采集所产生的整体性能消耗占了总资源的40%左右。为了降低系统资源占用,同时更高效的采集服务日志,我们开发了无磁盘IO的日志采集方式。具体流程是:采用类似Spring AOP的方式,对服务的请求进行挡截,采集服务的调用延时、服务状态等信息;同时,根据自定义的配置,抓取特定的入参和出参数据,所有这些信息都会被

20、封装到一个消息对象之中,并扔到一个内存消息队列之中进行缓存;与此同时,有独立的线程对这些消息进行预处理(如果需要的话),预处理结果也会被压入内存消息队列中再次进行缓存;最后,由独立的发送线程将这些内存消息队列中的原始日志或者预处理数据发送到远程的日志手机端。在日志的收集端,接进来的日志统一被扔到内存消息队列中缓存,再被分散到不同时间片段对应的二级消息队列中,由独立的分析器实例集合进行分析和落盘存储,通过这种纯内存+全异步的处理方式,我们就可以最大限度的避免资源锁的竞争,并榨取服务器的性能,从而实现对日志的高效的处理。通过这套体系,在不堵塞的情况下,任何一个服务节点的故障,在12秒之内就能被我们

21、的分析器捕捉到。如果把分布式服务框架比作是“咖啡”的话,那应用性能管理中的调用链监控及分析就是“奶昔”了,咖啡和奶昔是什么,是绝配!调用链比常规的日志收集方式更关注日志之间的关系,它通过一个统一的traceId把不同服务节点上的日志聚合在一起,来完整描述一个请求的调用过程,通过这个调用链路,我们可以发现服务的性能瓶颈在哪里、埋点的缺失情况、网络的质量等等一系列信息,通过调用链的聚合,还可以获取到服务集群的负载和健康度等更复杂的信息。调用链能够有效解决分布式环境下的监控需求,但在使用调用链的过程中,也要平衡全采集还是抽样采集、自动插码埋点还是手动埋点、实时统计还是预统计等等这些问题,如何权衡,需

22、要根据自身的特点及技术实力来做决策。今天由于时间关系,不在这里展开了,如果有感兴趣的同学,可以关注我在大会后两天的深度培训微服务治理的探索与实践。我们前面说了,企业服务化落地要两条“腿”走路,一条是服务框架,另外一条就是服务治理,服务化之路要走的顺畅,一定是两条腿都健壮。通过几年的努力,我们已经初步构建了服务化的治理体系,能够覆盖到服务监控和服务管控的大部分需求,其中管控的大部分能力是依托于蚂蚁金融云的能力来构建的,而监控这部分能力则是在SOFA-RPC的基础上,通过整合常规日志体系及APM监控的能力来综合获取的。服务监控这块,我们从各个服务节点抽取服务调用延时、调用状态、调用异常等信息,并汇

23、总到日志中心进行综合统计,得到各类的监控报表和监控大盘。通过错误信息,我们可以进行线上的故障定位定界;通过调用量的各级汇总,我们可以获取线上实时“水位”,进而进行客观的容量规划;通过调用延时和错误率,我们可以推断线上服务的健康度;在这些数据的基础上,基于时间维度,还可以获取到服务随时间的质量演进情况,这样的话,我们对整个服务集群就能有一个全面而实时的了解,并在此基础上,做出正确的管控决策。通过服务管控,可以将服务生命周期管理的调度指令下发到发布系统,进行服务的上线、下线、扩容、缩容等操作,另外限流、降级、调整负载的指令则会直接下发到各个服务节点中,由服务框架的SDK进行相应的调整动作。这样,通

24、过服务的监控(左边)和服务的管控(右边),就形成了针对服务治理的一个闭环的操作。在服务化的过程中,研发遇到的第一个困难,一定是调试。原来单体应用中的服务被拆分到不同团队,并部署在不同的服务器上,而本地只有一个服务接口。这时候要做调试,要么做P2P直连,要么做MOCK。采用传统的MOCk手段,要写一堆的MOCK语句,比如用mockito,就要写一堆的when.thenReturn.的语句,耦合度非常的高。我们是利用分布式服务框架提供的过滤器机制,开发了一个Mock过滤器,并通过Mock数据文件来详细定义要被mock的服务的名称、入参及出参。这样,当请求过来的时候,将服务名及入参和mock数据中的

25、定义进行比对,结果吻合,则直接将mock数据文件中的出参反序列化后作为服务的调用结果直接返回,同时远程调用的所有后续操作被终止。这样,就通过mock数据模拟了一个真实的远程服务。Mock过滤器的启用可以通过配置文件来实现“开关控制”,可以只在开发和测试环境启用,生产环境关闭。通过这种方式来构建服务的mock能力,我们就不需要写一堆的mock代码了,而且整个过程对业务逻辑来说完全无感知,完全把mock能力下沉到底层的服务框架。通过这种方式构建的分布式服务的mock能力,除了mock过滤器,最核心的就是Mock数据的构建。mock数据的质量直接决定了调测的质量!说起mock数据,它所做的无非就是匹

26、配哪个服务、输入的参数是什么,输出的结果又是什么。但实际的情况往往更复杂,你不可能通过静态数据去构建一个所谓的“当前时间”吧!因此,mock数据除了支持静态输入输出数据的比对,还需要支持动态匹配模式,也就是支持脚本匹配,我们所构建的服务mock框架,支持在mock数据中同时使用bsh和groovy这两种脚本。另外,一个服务集群中,往往会存在同一服务的不同版本,因此要真实模拟现实情况的话,mock数据也必须有版本的概念。除了以上两种匹配模式,我们针对实际情况,还开发了第三种mock模式,就是可以针对一个真实请求,部分修改它的回参来模拟出一个第三方的结果,这种方式在参数量非常多的情况下非常有用。所

27、以,要构建好一个Mock数据是需要投入不少工作量的,那么谁来做这个事情呢?这实际上牵涉到管理规范了。我们的规定是,服务谁提供,就由谁来构建这个mock数据,服务调用方可以在这个基础上做修改或者替换。但这还不够,由于服务会非常多,因此,对mock数据的管理一定要体系化和工程化。我的建议是,可以采用独立的项目工程对mock数据进行独立的管理和发布。目前,我们针对前端和服务端都开发了完整的mock能力,可以让开发人员在基本“无感”的状态下进行本地化的功能调测,同时提供一些自研的小工具来自动生成mock文件,以降低构建mock的难度和人力投入。为了有效降低制作mock文件的成本,我们还基于服务框架的过

28、滤器机制开发了“在线数据抓取过滤器”,它可以将指定的服务请求的入参和返回结果都抓取下来,并直接写成mock数据文件。通过抓取方式获得的mock数据文件,往往有更好的数据质量,毕竟反映的是更加真实的业务场景。当然了,这里还有一个合规性的问题,对线上数据的抓取是种敏感行为,大部分公司这么干都会很谨慎,一般都要做好数据脱敏的处理工作。对于我们,目前只在测试环境中进行数据抓取操作。事务的一致性和可用性问题是分布式环境下“老生常谈”的问题了,相信大家也或多或少遇到过这类问题。针对分布式事务,我们采取了3级应对的策略。首先,在分库分表操作中,我们会坚持“实体组”优先的策略,尽量按照统一的“片键”进行分库分

29、表操作,比如说,如果统一按“用户账户ID”作为分库分表键的话,那么用户相关的交易、资产、支付等相关信息都会落到同一个物理库实例之中,这样的话,针对此用户的相关操作,本地事务就可以生效,从而避免了分布式事务的使用。因为对于任何分布式事务而言,不管做不做资源锁定,为了有效保障事务状态,都需要额外的资源处理消耗。另外,我们还提供了自研的支持多级事务的TCC服务,以应对不可避免的分布式事务需求。采用TCC的原因最主要还是在于相对其它资源管理器而言,它相对简单,我们不用关注资源层面,只需要关注服务接口即可。上面的第二张图是TCC的典型架构模式图,相信只要研究过TCC的同学们一定看过这张图,第三张则是我们

30、自研的TCC的一个更详细的交互架构图,能体现更多技术细节,希望能对大家有所参考借鉴。总的来说,从我个人的理解而言,自己实现一个TCC框架(独立服务)并不麻烦,最核心的是要解决两大核心问题,一个是参与事务的业务数据的缓存和回放问题,我们在做TRY操作的时候,就需要将事务数据缓存起来,可以存到数据库中,当框架做Confirm和Cancel操作时,再用缓存的事务数据去运行特定的服务逻辑,所以,这就要求在TRY、Confirm和Cancel的方法构造上要有一定的约束,也就是相互之间要能够识别哪些入参是事务数据;另一个是父子事务的事务ID的传递问题,我们通过分布式服务框架的“非业务传参”来解决这个问题,

31、一旦某一个事务构建了一个事务ID,这个事务ID就会被放置到环境上下文之中,并随着RPC调用传递到远程服务,远程服务如果侦测到上下文中已经存在事务ID了,则就不再构建新的事务ID,这样的话,父子事务之间就通过同一个事务ID关联在一起。最后,最终一致性的保障一定是“对账、对账、对账”,这是最传统,也是最可靠的最后一道防线,这也是金融公司的基础能力,这里我就不展开详细说了。服务化之后,每个团队负责一部分的服务,经常一个业务会涉及多个团队之间的协同配合,如何让团队内部、团队之间的协作更高效,天弘内部也做了不同的尝试,从综合效果来说,敏捷模式会更适合一些。以我们移动平台团队举例,我们目前采用两周一迭代、固定发版的模式,同时每个迭代之内,采用“火车发布模式”,实行班车制,准点发车,这样的话,其它协作部门在很早之前就能大概知道我们的一个发布计划,产品方面也大概知道要把需求放入哪个迭代之中。这样,能够有效减轻部门间的沟通成本。在每期工

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论