《微服务架构.docx》由会员分享,可在线阅读,更多相关《微服务架构.docx(17页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、微服务架构注本文为我最近浏览?微效劳架构设计形式?的一点感悟我不准备详细去写对该书的读书笔记记录而是结合我们自己所做的一些微效劳架构理论情况做一些总结以及复盘。从单体应用到微效劳任何一个新的架构形式或者方法的出现一定是传统架构形式遇到了问题。而对于单体应用来讲常讲的问题主要包括了如下几个点。单体应用规模太大导致复杂度剧增难以开发以及管理单体应用开发交付以及变更周期变长敏捷性跟不上单体应用本身在性能扩展性上出现了问题在软件架构设计里面分而治之始终都是解决复杂性的一个关键思维方法。包括在传统软件架构设计里面对于大系统会进展子系统或者组件划分会进展接口设计集成设计等。架构的核心思维仍然是分解集成但是
2、传统架构在分解的时候没有做到单个组件的高度独立自治以及彻底解构。这个高度独立自治实际上要求组件或者模块从开发设计测试上线运行后期运维全生命周期都做到高度独立同时还要求配合的开发团队组织构造设计也独立。也正是这个原因进一步开展出了微效劳架构。也就是讲微效劳架构实际是传统组件化架构设计思想的进一步强化强化的核心就是独立以及解耦。微效劳架构思想的一个重点就是单体应用的拆分。讲微效劳一定会谈到扩展立方体。对于传统单体应用一般来讲扩展的方法只能是X坐标轴的通过扩展实例方式的程度扩展。而另外两个重要的扩展一个是功能拆分一个是数据库拆分。对于功能拆分实际不是新颖东西在很早组件化架构设计我们就做过将不同的应用
3、组件部署到不同的AppServer效劳器上对于应用层你只需要考虑解决类似Session会话保存全局配置以及分发等问题即可不会涉及到复杂的数据持久化问题。而真正难的是在数据库拆分。因为数据库拆分引入了两个大问题其一是分布式事务问题其二是大量操作跨库带来的分布式事务问题。数据库为何要拆分在单体应用开展到一定阶段后出现的性能问题往往都是DB层面的难以解决。数据库集群很难做到程度弹性扩展即使对于类似OracleRAC等商用集群软件本身也有性能扩展瓶颈。性能扩展到2到3倍后已经无法再扩展。因此单纯从扩展实例扩展来讲后面衍生了读写别离集群读写别离集群在应对读操作占比大的业务场景下实际是最正确的一种扩展方式
4、在这种方式下数据库本身并没有拆分为多个实例不会引入前面遇到的两个大问题。只要在数据库上搭建一个DaaS数据库访问中间件那么数据库底层的这种拆分以及变化完全可以做到对上层应用开发透明。当谈到这里的时候再来回首一下微效劳的一些核心点自然就更加清楚。微效劳是传统单体的拆分而且需要做到高度独立自治微效劳的拆分不仅仅是功能拆分更加重要是数据库拆分异步以及解耦是微效劳架构设计的重要指导思想微效劳间通过轻量高效的HttpAPI接口交互协同微效劳理论需要开发组织持续集成测试交付方式配套支撑场景以及问题驱动在前面谈微效劳的时候我就谈到过微效劳架构本身将导致开发集成运维复杂度全部增加。即使对于常讲的高可用性也仅仅
5、是高可用性以及弹性扩展才能增加但是对于高可靠性反而是降低。那么一个企业或者团队是什么原因理论微效劳仅仅是微效劳是一种架构开展趋势是技术热点是互联网大厂都在用吗而实际对于很多企业应用微效劳可以看到更多是团队里面总有一些技术狂热份子热衷于新架构新技术但是对于这些技术终究解决了哪些业务场景下的问题并不关心。这直接就导致了大量技术在不恰当的时候被应用。并不是讲微效劳不好而是讲对于架构师来讲应该基于业务技术团队资源本钱等多个维度来综合考虑终究应该在什么时候用什么样的技术最适宜。类似阿里的电商平台一天访问量上亿接近百万的TPS顶峰秒级成交都几十万笔这种业务场景下各个模块拆分为独立中心独立数据库是必然。不是
6、讲什么技术先进了必须使用而是为了知足以及支撑业务必须微效劳化。那么传统企业理论微效劳就一定要考虑微效劳终究能解决什么问题。假如这个问题没有想清楚就不要轻易去搞微效劳。其次就是通过其他传统方式能解决的也不要轻易去理想化的理论微效劳架构。比方一个业务系统运行经过中数据库出现性能瓶颈这个时候你可以考虑的是将历史数据进展迁移到备库增加备库单据查询才能或是前面谈到的构建数据库的读写别离集群或在数据库上构建二级索引缓存库来解决性能问题。再比方一些业务系统出现瓶颈并不是常规的OLTP场景出现问题而是单个业务系统数据库同时在支撑OLTP以及OLAP才能。这个时候你应该做到是将大量的查询统计以及数据分析功能移出
7、而不是对整个业务系统进展数据拆分。这方面的例子还有很多实际是想讲明一点很多业务系统的复杂度以及性能问题远远没有到必须进展功能拆分以及数据库拆分才可以解决的地步。微效劳拆分策略当聊微效劳拆分的时候先谈下传统软件架构设计里面的组件拆分。对于组件拆分可以看到常规的组件拆分实际是在应用层而没有到详细的数据库。这就导致了组件拆分后底层数据库仍然是一个中心点以及紧耦合点。包括组件拆分后实际架构规划的时候祈望通过组件间通过接口调用协同的后续在开发实现中往往也出现偏向即常讲的仍然是通过底层数据库的关联sql查询等来解决问题。所以你看到情况是组件间并没有什么接口调用而大量的耦合都转到底层数据库的耦合上面。到了微
8、效劳阶段的拆分实际上变成了两个重要的事情一个是数据库的拆分一个是基于数据库拆分后的功能拆分。对于拆分我前面写过两篇文章可以参考对领域模型以及上下文边界分析来划分微效劳的再考虑聊聊DaaS数据库即效劳以及微效劳下数据库拆分不管是采用的是传统的构造化分析方法还是当前类似DDD领域驱动建模里面的子域划分上下文边界识别等。拆分的重点仍然是在数据库拆分上面只是DDD方法里面将其理解为核心领域对象拆分领域对象拆分出来自然对应的数据库以及功能都进展了拆分。先梳理清楚边界并进展效劳拆分再基于业务协同以及业务功能实现来梳理以及定义API接口也就是讲微效劳拆分工作实际包括了三个方面的事情。即数据库拆分功能拆分AP
9、I接口识别以及定义。对于微效劳拆分来讲真正的困难点是在微效劳拆分的颗粒度上当重新读这本书的时候再次庆幸我们没有按书里面这么理想化的方法去理论微效劳去将微效劳拆分的如此细否那么真正是思路一条。因此在这里需要重申一个重要观点。微效劳拆分不应该是按标准理论理想化的拆分到哪个颗粒度而是应该根据实际的业务场景以及扩展性需求开发团队管理需求拆分到一个适宜的颗粒度。比方你如今做的是一个外卖订餐系统假如是类似美团APP这种规模进展细粒度的微效劳拆分势在必然。但是假如你的系统面对的市场仅仅是类似社区园区等私有云部署场景。那么这个系统从业务场景以及并发量上都没有必要做大的微效劳拆分实际架构上进展前后端别离独立缓存
10、库读写别离根本完全可以解决问题。因此微效劳拆分到哪个程度跟业务系统面对的业务场景以及问题有关而不要用标准的类似拆分方法策略去做拆分。类似面向对象的分析设计DDD领域驱动以及领域对象分析识别这些方法都没有问题这些完全可以应用到应用内部应用内部也需要组件化拆分而不是讲组件化后每个组件就必须拆分为独立的高度自治的微效劳。从API接口到异步解耦对于微效劳架构中的API接口设计在前面我专门写过文章来进展描绘。在这里还是想重新来讲明对API接口设计以及暴露里面的两个重要观点。对HttpRestAPI标准标准的理解要知道RestAPI更多的是一种面向资源的API接口设计方法。在早期我自己也坚持一个观点即需要
11、安装理想化的Rest接口设计方法来设计接口。但是当前我更倾向于仅仅将HttpAPI作为接口实现方式是否Rest风格并不是重点。即在接口实现中完全可以将所有接口实现POST接口方法而不用去区分哪些必须用GET哪些还得用PUT方法。固然都实现为POST方法后会对一些接口的在线访问以及测试带来一些不方便但是这个完全可以通过其它方式去解决掉。前后端别离以及大量API接口暴露API接口本身应该是粗粒度的但是实际在很多工程里面看到往往将数据库表的CRUD方法全部暴露为了API接口方法。这个一方面是领域对象层的贫血一个是前后端别离导致原来数据访问层的内部API接口全部都需要通过HttpAPI接口方式暴露。一
12、个内部的IT系统本身仅仅内部局域网使用只提供PC端的BS阅读界面也没有对APP端的支撑需求在这种情况下前后端别离没有任何必要。前后端别离反而带来了后端API接口大量暴露前端以及后端集成协同等大量问题。在这种场景下假如IT系统划分为5个微效劳模块这5个微效劳模块之间的API接口设计以及集成才是我们真正需要去关注的问题点。在当前微效劳架构设计里面微效劳间的接口协同微效劳本身前后端接口协同全部混杂在一起实际导致了后续整个微效劳体系里面的API管控治理完全失控。基于Saga分布式事务前面谈分布式事务的时候更多谈的是事物补偿或事务最终一致性保障但是很多长周期的事务仍然是API接口的同步调用方式来实现。即
13、当API接口同步调用的时候微效劳间并没有彻底解耦。要解耦必须是基于事件或者消息形式的异步调用方式。Saga即是一种异步消息事件机制下的分布式事务解决方案。Saga是由一系列的本地事务构成。每一个本地事务在更新完数据库之后会发布一条消息或一个事件来触发Saga中的下一个本地事务的执行。假如一个本地事务因为某些业务规那么无法知足而失败Saga会执行在这个失败的事务之前成功提交的所有事务的补偿操作。Saga的实现有很多种方式其中最流行的两种方式是基于事件的方式。这种方式没有协调中心整个形式的工作方式就像舞蹈一样各个舞蹈演员按照预先编排的动作以及走位各自表演最终形成一只舞蹈。基于命令的方式。这种方式的
14、工作形式就像一只乐队由一个指挥家协调中心来协调大众的工作。协调中心来告诉Saga的介入方应该执行哪一个本地事务。当重新来考虑分布式事务的时候再次印证我的一个观点即微效劳拆分太细导致引入了很多完全没有必要的分布式事务问题增加了开发集成测试以及后续监控运维的工作量以及复杂度。比方书里面谈到的一个例子对于一个在线订餐系统提交一个订单这个本身是一个很容易实现的功能但是在微效劳化后订单提交涉及到用户校验账户校验厨房工单生成多个独立API效劳接口调用。这个就涉及到这些API接口的事件编排同时在编排中你还需要考虑出现异常时候的补偿回退考虑消息执行顺序等众多问题。这些急剧了增加了一个功能实现的复杂度。当你本身
15、开发的系统就不存在海量并发以及高性能需求的时候我实在难以找到任何理由将微效劳拆分的如此细引入这么多的复杂度。实际上以上的分布式事务场景应该更多地应用到大系统间的分布式事务协同上面比方采购系统提交订单的时候同时涉及到工作流平台中的工作流实例启动涉及到预算系统的预算校验这个时候才要分布式事务来实现是有必要的。跨系统出现上面这种分布式事务处理以及协同场景这个量完全可控。但是你微效劳拆分得太细你在实现应用中任何一个功能都引入上面这种分布式事务问题基于事件的编排以及补偿问题可想而知已经不是简单的复杂度问题而是后期的系统可靠性以及可运维问题。怎样彻底解耦前面谈到了假如是CUD操作可以异步方式来实现解耦那么
16、对于查询操作怎样处理。假如一个查询查找本身还涉及到多个微效劳API接口的组合这个时候怎样实现解耦。对于查询操作一般来讲都是同步操作用户端点击查询后会等待数据的返回这个时候假如需要调用多个微效劳API接口数据进展组合那么底层某个微效劳模块如此异常将直接导致整个查询功能持续异常。即假如存在查询操作那么微效劳间仍然是紧耦合在一起的。我们祈望的微效劳间通过消息以及异步来彻底解耦这个目的并没有到达。当然实际上可以考虑两个方法来解决这个问题。其一就是将常用数据缓存查询的时候直接访问缓存库。其二就是将微效劳底层数据库需要分享数据进展同步同步到一个大的分享ODS读库专门来提供查询效劳才能。在一些工程的CQRS
17、命令查询职责别离理论中根本即采用的这个思路。通过这种方式来实现微效劳间的彻底解耦。当然也引入了另外两个依赖点一个就是消息中间件一个就是缓存库或者分布式ODS读库。这两个点的稳定性就直接影响到整个系统的稳定性。采用CQRS形式最大的一个问题点就是无法实现命令以及查询两局部内容的强一致性保障即很可能你界面上查询到的数据不是最新的持久化数据库里面的数据这个本身以及消息管道异步写入的实时性又关系。其次在使用CQRS形式的时候有一个重要假设就是在事件以及命令发出后无特殊情况在事件接收方都必需要可以接收事件成功处理否那么就存在大量的异常错误消息的异步回写反而增加系统的复杂度。施行CQRS引入的整体复杂度也
18、不是一般的小工程可以玩得起的。同时对于CQRS框架的施行不是简单的设计形式以及开发复杂度问题更加重要的仍然是是否可以承受最终一致性要求同时在该要求下将传统的同步恳求下业务功能以及逻辑处理机制转变为异步事件价值下的事件链驱动形式。要实现这种转变就必须可以拆分出独立自治的命令以及事件同时确保这些事件在朝后端业务功能以及逻辑模块发送的时候可以处理成功即该做的校验必须提早做完。微效劳网关以及API网关对于API网关可以以先参考我头条发布过的相关文章。于API网关以及微效劳网关实际实现的核心功能根本一致但是要注意到微效劳网关一般是在微效劳架构体系里面的内容。而API网关一般是可以独立在微效劳架构体系之外
19、的内容。也就是讲API网关以及微效劳整体框架体系更加的松耦合。API网关一般具备独立的效劳注册接入负载平衡以及路由才能而微效劳网关一般那么是通过以及效劳注册中心的集成来实现效劳注册发现负载平衡以及路由。应用范围的区别在这里重新强调下微效劳网关以及API网关实际在应用范围上有明显的区别。即微效劳网关一般应用在单个微效劳应用内部十分是在存在前后端别离情况下。而对于API网关那么是应用在组织级实现多个微效劳应用之间的集成以及协同才能。单个微效劳应用完全没有必要采用API网关直接使用微效劳网关。比方当你采用SpringCLoud框架体系的时候你直接采用框架里面的Zuul或者SpringCLoudGat
20、eway即可。但是当你在做组织级的多个微效劳应用间集成的时候这个时候需要的脱离单个微效劳框架体系的的一个外部集成中间件因此不能以及微效劳框架绑定太死。其次你会看到跨应用间的集成管控的粒度不是到微效劳组件而是要细化到一个个的API接口。因此这个时候启用API网关就是必须的。当你在组织级启用API网关的时候发现一个新问题。即对于整个组织级来讲遗留系统以及单体应用的微效劳化本身有个经过在这个经过中一定是传统架构以及微效劳架构共存。新的RestAPI接口以及老的SOAP接口以及消息协议共存阶段。而API网关本身对老的接口协议适配才能并不好。对于类似ESB总线来讲固然侧重但是可以完全兼容以及覆盖API网
21、关具备的才能。因此在这种情况下API网关反而变得鸡肋。API网关是否该做类似效劳编排组合的事情简单来讲API网关不应该做这件事情传统的ESB总线往往具备这个才能但是API网关不合适来承载这个才能。假如做了效劳编排的事情一个是让API网关本身从单纯的技术中间件变成了承载业务逻辑的中间件其次就是该才能本身也将让API网关变得更加重。因此最好的方法仍然是独立一个微效劳来实现效劳组合以及编排发布组合后的领域效劳或者组合效劳才能这个在我前面文章专门有谈到过。API网关本身的中心化问题不要简单地认为中心化架构就一定不好中心化架构本身通过集中管控以及拦截的方式可以很方便地实现类似API接口平安日志路由流控等
22、各种管控才能。在谈微效劳管控治理的时候中心化的API网关是一个重要的实现思路以及手段当然在前面我也提到了整体的开展趋势应该ServiceMesh化实现完全的去中心化架构。这个ServiceMesh化本身又可以以及DevOps容器云等云原生技术形成一个完好的整体。但是要意识到的点仍然是在于组织管控以及标准化推进的力度假如在组织级很多技术标准推进不一致应用系统改造存在前后逐步演进那么这个时候你很难简单的去实现ServiceMesh化架构。简单来讲即是对于传统IT架构的逐步微效劳化本身并不合适采用ServiceMesh。在谈微效劳架构的时候经常有人谈到完全的去中心化但是没有搞清楚为啥要去中心化。即使异步消息集成消息中间件仍然是中心点。当组织级标准标准技术要求不统一的时候管控才能达不到时候很难完全去中心化这个时候中心化方式反而是一个好的选择。最后做下简单总结如下按照理想化的微效劳方法来设计以及施行微效劳对于大局部传统企业信息化来讲不适用同样照搬互联网微效劳架构化方法同样不适用。企业IT架构在微效劳转型经过中更多应该基于业务场景以及问题驱动借鉴微效劳拆分以及解耦的思想充分考虑敏捷交付弹性扩展以及性能开发难度以及资源本钱投入后期管控治理多方面的平衡。来源s:/toutiao/i6925193987997696516/JAVA高级架构v