微服务架构介绍_第1页
微服务架构介绍_第2页
微服务架构介绍_第3页
微服务架构介绍_第4页
微服务架构介绍_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、微服务架构介绍微服务是个说的挺长时间的概念,也是比较成熟的技术体系。像 Spring Cloud,甚至提供了 微服务所需要的全套框架,包括注册中心 (Eureka)、配置中心(Config)、断路器(Hytrix)、 API网关(Zuul)等组件。微服务体系庞杂,每个组件都能独自成章。微服务与更早就起来的SOA是什么关系?个人觉得如果从概念上来说,微服务和 SOA都是 一回事,强调把整个系统,按照多个服务的方式去组合及通信,而不是揉合在一起,但它们的 内涵有很大的区别。SOA诞生在早期企业级的应用,其业务复杂、技术体系多样,SOA强调的是各个服务之间, 尤其是异构系统、遗留系统之间,建立起一套

2、统一的协议和通信(SOAP),以及寻址服务(UDDI), 它的侧重点在集成和兼容;与 SOA同期的另一种概念ESB(企业总线),强调通过一根总线服 务,把所有服务串联起来,由 ESB总线来屏蔽各种不同业务系统自身业务 /语言/协议的 特殊性,各服务以一种统一的方式,与总线相连,从而降低接入成本。这两种概念,我感觉在国内没有太发展起来。一是国内的软件起步相对较晚,系统的整体复杂 度多厂商、多语言/技术栈、历史遗留系统的问题,还不算突出。而对于公司内部的产品 系,又没有必要使用SOA、UDDI来做复杂的集成。随着互联网的兴起和用户量的迅速爆发, 企业自身的产品的微服务化的需求,快速发展起来,而与此

3、同时SOA这种以XML为基础的SOAP协议、以寻址为主要作用的UDDI,不能使用互联网产品的发展 SOAP的XML协 议内容太多,造成性能明显下降;HTTP协议的效率不如RPC ; UDDI只有寻址,缺少服务治 理等功能。在此种大背景下,以服务切分 +服务注册+服务治理+限流降级+RPC+监控等为主要 内涵的微服务,就快速发展起来的。国内的阿里巴巴走在前列,以 Dubbo为代表在国内互联 网企业中得到广泛应用;后来 Spring官方发布Spring Cloud,揉合了一系列自研或其他企业捐赠的开源项目,发布微服务领域的Spring Cloud产品。各自都有各自的优势和劣势,而随着这些年来,微服

4、务的继续下沉(sidecar和service mesh)到基础设施层,给微服务的治 理带来了新的方向。微服务的关键特性服务粒度服务的粒度,切分到多大算合适?太粗的话,这服务就涵盖过多的业务逻辑,从而难维护、易 出错;太细了,就会搞出很多的工程,造成很大的工程维护和通信成本。主流说法是依据康威定律一一团队的交流机制应该和组织机构相匹配。应用到软件领域来看, 如果某个应用,需要多个组织之间一起交流和修改,那么它的交流机制就大于组织机构了,出 现了不匹配的情况,那么这个应用很可能就太粗而需要拆分。这里有个不太好懂的地方既然系统架构和团队组织机构想匹配,那我们是先定系统架构呢,还是先定团队组织机构呢?

5、这有点类似先有鸡还是先有蛋。我觉得可以这么来理解:无论是团 队怎么定、还是架构怎么定,这都是跟着业务的发展而发展的,可以说都是业务的衍生发展而 来。所以系统架构设计,首要做的还是业务理解和切分业务切分决定了服务切分、业务切 分也决定了团队组织。业务切分有两种简单办法:参照业内同类公司的划分:比如电商,业内比较成熟的:支付、库存、订单、搜索、用户等;将自身业务的主要信息流画出来,先找出其中的名词或动名词,它就可能是个服务eg :在我们的线上贷款业务中,典型的user case是这样:用户导入几项金融资料数据系统根据信息清洗出部分衍生变量系统跑欺诈规则系统计算授信,给出额度用户试算得到月费率和利息

6、系统人工信审系统放款到还款日时用户还款或者我们系统主动扣款将其中的名词整理出来,整理流程大概就是如下图:这些都是候选服务。根据其复杂度和相关性,做适当的拆解和合并,形成了如下几个子系统及服务。治理范围从服务的角度来看,对外公开的是契约即我们系统提供哪些特性,而内部算法/数据都应 该隐藏起来,而在不同服务间是共享数据库还是独享数据库上,实践中的冲突和困惑,体 现地比较明显。我们假想个流程,ServiceA的李雷需要更新User表的某个字段,如果大家数据库表都共享的,李雷只要写个SQL就解决了。但一旦把User表服务化后,归到UserCenter这个服务 自治之后,问题就麻烦了:李雷要去找User

7、Center团队一假设是韩梅梅接了这个需求,好在是个女生,男女搭配干活 不累讲清楚他的需求或提供需求文档;韩梅梅理解了需求,设计接口、提供文档、评审并准备开发;韩梅梅可能手里有其他事,所以这个需求大概要等几天才能开发;终于韩梅梅开发完了,她要自测、部署;上游李雷开始联调,如果有问题,需要双方再沟通解 决;联调完毕上线,韩梅梅的 UserCenter先上,李雷的业务系统再接着上;从这可以看到,一旦一个人、一个系统做的事,变成了2个人、两个系统来做,那要多出多少麻烦了。所以我完全理解,在公司早期,所以业务系统共享一套数据库表,是多么地务实。我 们功夫贷在创业之初也是这么做的,在创业 2年后,它的弊

8、端开始密集体现,而服务化改造过 程中,我们也是付出了相当大的代价。随着用户量和数据量的上升,这种共享数据库表的最明显的弊端就是慢查询越来越多因为谁都可以操作任何一张表、而开发过程中或者是对业务理解不够、或者是SQL能力不足,很容易写出慢SQL来,其结果就是导致 DB的CPU飙升到100%、或者是IOPS被打满, 从而全APP被拖慢甚至无法提供服务。这种危害是相当巨大的。所以,从运行时的慢SQL带来的巨大杀伤力来说,数据库应该是隐藏在服务内部,该服务由熟悉该业务的固定团队维护、也会做很多优化。虽然开发阶段慢了,但是运行时稳定了、系统的可用性得到了保障。只是这件事,不应该在创业初期就做,那样会比较

9、严重地放缓系统迭代速度、更应该在系统规模相对较大的时候来改造。当然,我们说改造是要付出代价的。不仅之前的一个库中的表,要分成不同的库,各服务的程序要做不小的改造,其中最困难的是,同一张表的字段,可能会属于各个不同的应用。看下面这个User表。名称碇像 姓昵密头开始的时候,User表只包含了完全业务无关的属性,但随着系统的发展,一些和业务相关的字段(上图红色部分)逐渐地被加进来这也不完全是决策时犯的错误,而是本身这属性是否和业务有关,也不是很容易界定。所以逐渐会发现,很多系统都会依赖这张表,从而交织难以拆分。各个服务可能都需要有这张表,而各自维护自己所关心的那部分字段及功能。在我们的实践中,服务

10、化的过程以及数据迁移,大约是这样的步骤(以用户中心应用为例):1.创建新应用UserCenter,梳理清楚其的业务边界和所涉及的数据表;2.收集和分析其他系统对这些数据表的需求,并在UserCenter中开发接口,以备上游系统调用;逐渐改造上游系统,使其由原先的读取数据库,修改为调用UserCenter接口。由于有多个上游系统和功能需要改在,因此这个阶段会比较长,上游系统在这个时间周期内,也会访问接 口服务”和直接访问数据库这两种形态并存; 检查并确认上游系统都改造完毕上线,此时理论上应该没有上游系统直接读取UserCenter的 表了,都通过接口了,此时准备迁移 UserCenter的表数据

11、;建立New UserCenter DB,并通过 DB同步机制,实时地将 UserCenter的表数据由老库 同步到新库。在新库同步完成之前,UserCenter的应用仍然使用的是老库里的表;新库同步完毕,UserCenter应用切换到新库,此时所有的新数据都会进新库,而老库理论上 是不用了;断开新老库的同步链,同时rename老库的表(先不删,同时在rename前一定要断开同步链,否则新库也会被同步rename掉了)。如果此时万一有某个系统的功能,在之前的系统改 造/测试中遗漏了没被发现,仍然是直接读取的数据库表,那么这时候就会报错(因为表名被rename掉了,找不到了)。此时就是个恢复窗口

12、,赶紧把表 rename回来,减少损失,然后 再继续处理。这也是前面千万不能直接把老表删除的原因;运行几天没问题之后,再把老库的表删除,整个服务化过程结束;服务组合在微服务之后,各个系统只对某一块业务负责,那么就有可能需要对服务做一些聚合。下面是 常见的两种模式:这是聚合服务的模式,由 web应用去负责聚合后端服务或做个性化处理,这是它的好处一 可以根据自身的业务做任何组合和处理,而它的坏处也很明显一对于不需要特殊处理的,也 得过它一道。这是后台服务自包含的模式。某个后台应用,依赖于其他服务,于是就将其他服务的相关调用 都处理完了,或者这么理解后台服务也有多个层次:库存服务、支付服务、发票服务

13、是最底层的,交易服务是更上层一些的共享服务,从而达到封装细粒度服务的目的,与此同时,它的个性化也就丧失了。假如有个交易,是不需要发票服务的,那么这种模式就不是太灵活。从我个人的经验来看,我是倾向于聚合服务这种模式。每个前端应用,还都是应该有个自己的后台服务,去完成很多小的功能(比如更新APP版本、展示首页广告、记录埋点等 APP特有feature)、以及聚合。而对于不需要 App-Server处理、直接使用后台服务的,应该能够 通过gateway直接调用,而不需要 App-Server来做代理转发。容错容错的目的就是在出现问题的时候,仍然能够正常提供服务,其具体表现形式有这么几种:当调用下游服

14、务B出错的时候,可以在安全的情况下考虑重试;当调用下游服务B出错的时候,可以调用替代服务B;当调用下游服务B出错的时候,是否可以返回某个默认值、或者返回最近一次的值当调用下游服务B超时的时候,如果超时请求达到一定数量,则需要熔断,以保证自身其他服 务能正常提供服务,而不会被拖垮;当调用下游服务B出错的时候,能否以异步+定时任务补偿的方式代替?上面这些特性,有些是通过RPC框架来实现(重试)、有些是应用控制(调用替代服务、异步+ 定时补偿)、有些可以通过Hytrix这样的断路保护框架来实现。容错也比较简单,但为了容错 确实也需要增加不少开发工作量,它就像买保险,有的人看重风险、愿意付出一些代价来

15、买一 份适合的保险;有的人比较乐观,不相信灾难会降临到自己身上,所以这就看一个公司对自己 的要求了。从我个人的观点来看,公司到达千万用户级以上,就需要比较严肃地考虑这个了, 因为一次全局事故,带来的损失就会是不小。限流限流主要有两种算法:令牌桶算法和漏桶算法。漏怖算法思路很簿羊,水:清松 免进人到虽桶甲 漏插成一定的速擅出水,当水淹人速度迂大会克侵潘出.可以毒出诋桐胃法能强 行限制戒橙的传辘染率.的 nArrdrpAiNtd Ihv A口Fb at a ixrswTl啊珂1漏楠耳透示室更对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能

16、就不合适了,令牌桶算法更为适合。如下图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。从互联网实践的角度看,我觉得这两种方法都不是很理想。主要原因是看我们怎么理解流量控 制这个事情。在互联网领域,系统的最大处理能力,是一个比较核心的指标。假设系统(或某接口服务)只能同时支撑10000个请求同时处理(这也是非常容易模拟测试的),那么它所关 心的,就是在任何一个时间点的执行中任务,是否超过了10000,而这是令牌算法和漏桶算法都提供不了的。令牌算法:单位时间内生产的令牌是固定的,而令牌桶就相当于一个蓄

17、水池。如果令牌不被马 上用完,令牌桶可以存储一部分。它是从请求数(开始处理的)的角度,随着蓄水池中的令牌多少,而相应请求多或者少。它不能衡量当前有多少请求正在进行中。且蓄水池的大小,并不 是它自己可以说的算,虽然它有令牌,也还需要系统能处理才可以。漏桶算法:单位时间内可以处理的请求是固定的,持续恒定,没有令牌桶来做蓄水池。它同样是从请求的角度出来,无法衡量当前的并行处理任务。所以这两种算法,我认为它都不是从精确的系统承载量角度出发,更像是一些预估或外界因素所引发的流控比如该系统1分钟只允许处理100个请求,以一种比较粗略的方式、来保 护系统不过载;该系统依赖的第三方不能超过每天XX次的请求量;

18、从请求出发的角度,还有令牌算法的优化版滑窗模式。以X个滑窗作为一个周期,比如1 秒作为1个窗口,3个窗口作为一个周期,在这个周期内令牌蓄水池。3秒到了则在排队等待令牌的请求都置拒绝。这样防止在流量阻塞的时候,随着时间推移,很多用户已经等不及离 开了,而他们的请求还在这里排队,导致最新用户的请求无法获得令牌。而如果从系统承载力的角度,既能最大发挥系统能力,又不会过载,个人认为最好的方法响 应模式一访问开始前,计数器+1;访问结束,计数器-1 ;保证计数器不超过阀值,也就是当前系统正在处理的任务,不超过阀值。从另一个角度看,令牌算法和漏桶算法被很多框架完好支持,比如Nginx,这样对于大部分接口,

19、尤其是处于安全角度考虑的限流,就是个很好的策略。在Nginx中配下就可以了,不需要业务去衡量自身负载、再开发相应代码。所以这也是种取舍一如果要快速覆盖、尤其在产 品初期,尽量地保护自己的系统,尤其是安全原因,那么令牌或漏桶算法是很好的选择;如果 针对一些核心接口,希望能在保护自己系统的同时、尽量多地发挥系统潜力,那么就开发响 应模式是更好的选择。一致性CAP(Consistence、Available、Partition)理论是很熟悉的分布式理论同一时间 CAP不能全部满足、只能满足其中两个。而由于分布式系统的特点,Partition是必须要满足的,所 以只能要么CP、要么AP,即要么系统可用

20、,但数据可能不一致;要么数据一致,但系统不可 用。这里对为什么Partition必须要满足解释一下。CAP主要是针对有状态、即有数据的,典 型形态就是存储类产品。因为数据才有一致性、分区同步这样的场景。在存储类产品中,为了 避免单点故障,都是需要主从结构、或者集群结构,这就势必有相互之间的数据复制主从 的话,是主向从复制;集群的话,是多副本复制。这就必然涉及到网络通信,而网络我们说不 是非常稳定的,满足Partition”就是在网络不稳定的时候,比如主和从网络短时不通了,这 时候产品还能够正常提供服务。这就是Partition必须要满足”的原因,否则就有较大的单点 风险。既然P必须要满足,则只

21、能选 AP或者CP 了。就互联网企业来说,保证服务可用性更为重 要,所以AP往往是主流选择。在我的经验中,金融财务相关领域可能会用到AP这样的强一致,这往往是通过有 ACID特性的RDMS(Oracle、MySQL)来实现的。前面我们提到,分布式的服务治理,数据被隐藏到服务内部了,那么对数据的修改就由原先的 直接操作变成了接口调用,原先可能可以通过Transaction来实现多表更新的 ACID,现在实 现不了了,那在保证 AP的同时,Consistence怎么办呢?此时BASE理论也就应运而生。 BASE(Base Available、Soft State、Eventually Consis

22、tence)基本可用、暂时不一致、最终一致。短时间内数据不一致,可能会造成一定的脏读,但最终会达成一致,而达成一致的速 度窗口,也就是个比较重要的指标。Paxos和Raft算法是两个主流的最终一致性的算法。从 BASE的定义来看,对于准确性高度敏感的金融财务领域,可能就不合适。在存储类产品中,使用Paxos或Gossip算法,主要是用于协调各个节点的状态和版本,以 完成同步。而在微服务领域中,我们面对的是各个RPC或http通信的不同类的应用服务(可 能使用这些算法也可以,复杂度应该是比较高,反正我是没试过),那么又怎么做到最终一致?主 要策略有两个:撤销、补偿。前者是努力恢复到操作前的一致状

23、态,后者是努力保证成功、达 到操作后的一致状态。看下图,Server的某个业务操作中,要分别调用Service-X、Service-Y、Service-Z三个服务,才能完成。此时如果调用 Service-Z的过程中出现错误了,怎么保证最 终一致性?按照上面的撤销或者补偿,就有两个策略: 撤销:Service-X和Service-Y提供反向的撤销接口。如果调用Service-Z失败,则调用Service-X和Service-Y的反向撤销接口,以恢复到操作前的状态。如果撤销的过程中失败?呵呵,那又要补偿了。补偿:Service-X和Service-Y都执行成功了,那么Service-Z调用失败,在确保Service-Z只要恢复正常、必然能执行成功的前提下(无论是系统自动还是人工)”,通过定时任务重试或者MQ的机制,补偿重试,再不行人工处理,直到Service-Z成功,以达到都成功的状态。这里确

温馨提示

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

评论

0/150

提交评论