今天准备再谈下微服务,对于微服务相关基础文章,包括企业传统IT架构如何平滑进行微服务化转型都可以参考我头条发布过的相关文章。
大家可以看到实际中台概念比微服务出来的晚,很多人觉得中台被互联网网和相关厂商炒作的太例会,最终从建设成效,投入产出比多方面都没有达到企业的希望,也服务敏捷满足企业的业务战略需求,因此现在又很多人站出来提拆中台或反中台。
任何一个新鲜事物,本来架构设计或思想是好的,但是脱离了企业实际的业务目标,业务场景和需求空谈,那么再好的东西就变成了垃圾。
微服务究竟在谈什么?
我不准备再重新去阐述微服务的概念和定义,而是重新来思考下微服务这个概念的出现和应用场景。实际上你可以看到,在没有微服务这个概念的时候我们也在做一些类似的事情。
比如在很多年前我们做SRM系统,后续准备在SRM系统里面扩展招投标管理模块,但是后来一思考发现招投标管理本身由招投标部负责,业务相对独立,功能也高度自治,和外部SRM接口集成点也体现粗粒度特性。
因此我们将招投标作为一个独立的子系统进行建设。
再比如企业引入了ERP系统后,发现对于采购,物流,合同,预算等能力都需要在ERP上二次开发才能够满足需求。但是实际发现这些能力本身和ERP之间也是松耦合关系,比如对于采购管理中的询价,洽谈,流程审批等。ERP只管理最终的供应商,采购请购单和采购订单,而实际你这些单据如何形成往往并不关系。对于ERP的财务模块也一样,ERP只关心最终形成的应付凭证或总账凭证,对于这些凭证应该走什么的报销或审批流程形成ERP也不关心。
那么外围的很多扩展业务实际和ERP核心是松耦合的关心,因此可以看到很多企业围绕ERP系统构建了外部多个独立的子系统,类似采购,报账,预算,合同,HR人力资源管理等。这些系统最终又和ERP之间完成集成和协同。
所以你看到在微服务概念没出来前我们就在做一件事。
简单来说就说不要把系统做得越来越大,系统越庞大后续可能越难管理,系统本身也难以扩展和运维。如果发现高度自治和松耦合的业务,可以考虑独立建设。
注意这个实际和当前微服务谈的大的单体应用要拆分为更小的微服务是一个道理。在互联网电商架构里面经常看到用户中心,订单中心,库存中心,支付中心。这个映射回企业内部IT,不是已经拆分为了类似主数据平台,采购子系统,WMS子系统,报账子系统吗?所以并不是说原来IT系统构建的时候没有考虑拆分,而仅仅是拆分到哪个度的问题。
互联网为何先搞微服务和单体应用拆分?
互联网应用由于特殊性,直接面对C端用户的时候,往往会出现海量数据和大并发量调用。这样就导致原来的单体应用在性能上撑不住了,也没法进行能力扩展,无法进行后续的运维和管控,不得不拆分。其次就是由于同时存在PC端和APP端,发现很多东西重复开发了,需要整合,因此出现横向进一步拆分和前后端分离。
那么再回来到企业内部IT来说,一个采购系统本身用户主要是采购部门人员,业务量和并发量都完全可控,也没有明细的性能问题。原来单体的集群扩展和冗余设计也完全能够满足业务需求。
那么这个时候你再去拆分为更小的微服务的理由是啥?
再次明确传统的微服务架构改造,一定是围绕业务目标和场景驱动,而不是简单的技术驱动。比如集团型企业搞了集中化,全集团几十万用户使用系统,同时又要考虑去IOE,那么传统的单体应用无法支撑和扩展,这个时候才是推动微服务的驱动力。
对于任何一个企业的IT建设,都应该是基于业务场景和业务目标需求,采用当前最适合的技术和工具来解决问题,而不是采用最先进的技术。任何一个先进的技术往往都需要当前企业在组织架构,项目管理,团队,技术储备,管控治理各方面的能力储备达到一定程度来配合。否则先进技术反而带来的是低效能。
微服务带来哪些问题?
如果企业本身的IT成熟度没有达到一定阶段,显然是不可能推行实施微服务架构的。这个道理前面已经谈到过,在企业IT建设中,如果连粗粒度的业务系统以及它们之间的集成都管理不好,那么更没有能力管理细粒度的微服务模块。
即使企业IT技术和成熟度达到一定水平,在推广微服务架构还存在的难点如下:
首先是架构设计能力的显性化导致的内部问题暴露,即架构设计这个工作的输入,输出和过程需要更加的显性化出来形成团队都认同的标准工件。一个业务系统没有拆分开时候,虽然有架构设计和组件划分,但是这个工作是属于团队内部的事情,即使架构设计不合理,在后期集成也可以通过诸多变通方式解决掉。而现在是不同的微服务模块可能分派到两个独立的团队开发,原来属于自己内部黑盒的问题变为团队间问题。
简单来说你原来藏着或没做规范的东西太多,而现在这些不能再藏着掖着了,当真要把这些东西拿出来的时候,你才会发现你原来架构能力是有欠缺的。正如我们理解了一个东西,那么要让我们清楚的讲出来困难,那么我们的理解有欠缺。对于我们能讲清楚的东西,要系统的写下来有困难,那么说明我们讲的结构和条理有欠缺。
其次管控要求和规范体系的建立不及时,对于管控要求可以看到如果两个微服务模块分给同一个团队开发,如何才能保证开发的团队保持两个模块的完全独立和解耦,两个模块间不会出现相互交叉的数据库直接调用,也不会存在直接绕开Service接口的其它耦合调用?这些如果没有完整的管控和检查体系我们很难约束。
其三是微服务架构下导致的开发复杂度增加, 只谈微服务架构的松耦合和高扩展性,而不谈开发和集成复杂度的都是耍流氓。
实际上当前很多企业对微服务架构并没有如此迫切,互联网很多企业推行微服务架构更多的还是考虑到巨大的业务并发量下的系统弹性扩展能力,而实际大多数企业内应用往往并没有如此海量并发。其次,即使在并发量增加的情况下通过进行代码本身的优化,数据库调优或者升级硬件服务器资源都可以较好的解决性能问题。而做这些事情投入的成本远远小于微服务架构带来的开发复杂度增加成本,后期的运维管控成本。
要做到完全微服务模块独立,微服务架构下最大的一个变化就是数据库也拆分开了,原来的一个业务系统如果分为5个微服务模块,那理论上就是5个独立的后台数据库,而且数据库间还不能随便相互连接和访问。只有这样微服务模块才能做到独立部署和管理。
由于数据库拆分带来两个问题,其一是我们原来很简单的一个跨表查询操作现在无法做了,我们必须调用两个微服务模块提供的服务,查询到数据后再到逻辑层进行组合。其次最大的问题就是如果一个业务操作需要同时更新两个微服务模块的数据,由于服务本身无状态,导致了这种分布式事务问题很难解决。
企业内业务系统很大一个特点就是业务逻辑和规则相对互联网更加复杂,而且有更高的事务一致性要求。正是由于这个原因,无法解决好分布式事务的问题都将直接导致后续数据不一致和业务错误。
原来通过调用项目内一个API方法就能解决的问题,现在要调用远程WS接口才能解决,这本身就增加了开发和调试的复杂度。一个微服务模块与外部其它模块的集成和协同越少,你会发现该微服务模块和传统业务系统开发没太大区别,但是当其涉及到完成任何一个功能都需要调用外部微服务模块的服务接口时候,其开发模式和效率上就会带来巨大的变化。
其四是微服务架构下导致的集成复杂度增加, 任何一个微服务模块在外部协同上都存在两个点,一个是模块本身要消费和调用其它微服务模块提供的服务接口,另外一个是模块本身又需要将其业务能力暴露为服务接口给其它微服务模块使用。
如果一个微服务模块要同时支撑PC端和APP端,可以看到微服务模块暴露的服务还需要统一提供给前端的展示用。那么可以看到一个微服务模块需要完成自身组件层和展现层间的集成,同时又需要完成多个微服务模块组件间的横向服务集成。
如果我们将消息,日志,流程,4A等能力下层到平台层微服务模块,那么一个组件要跑起来还涉及到和平台层的多个技术类微服务模块集成。在如此复杂的集成场景下,要将复杂的跨多个微服务模块的横向端到端业务跑通,其涉及到的模块数,接口数都远超原有单一系统的模式。
一个业务系统如果没有拆分为微服务模块,那么其它内的模块间集成和集成测试是系统内部的事情,但是一旦拆分为多个微服务模块,那么这种集成就变成外部第三方的事情,或者必须要显性的事情。
对于一个微服务模块来说,当其需要集成的外部微服务模块和接口都变多的时候带来什么问题呢?这个问题大家容易理解,即该模块究竟是否稳定已经不是模块本身的事情了,而是涉及到诸多外部依赖模块是否稳定。
更简单说本来原来我自己可以确认稳定的事情,现在我无法确认了。即使每个模块的稳定度都90%,但是你会发现一集成起来90%*90%*90%,那么稳定性就下降得很厉害。正是由于这个原因,我们要求在一个大体系里面,每个微服务模块的开发质量都要得到保证,这已经不是单个模块自己的事情,而是直接影响到大系统的质量。
最后是微服务架构下的运维问题, 在实施了微服务架构后,运维的复杂度也是成倍增加,任何一个微服务模块出问题都可能影响到整个业务应用的功能使用。我们在运维时候不仅仅要健康单个微服务模块,还需要健康所有的接口服务监控状态。
如果跟Docker集成了,我们看到整个性能监控和问题分析都会变麻烦了,没有实施微服务架构前发现问题,我们直接可以看应用服务器上类似tomcat或jboss日志,而实施了微服务架构后,应用容器已经是自动部署和动态分配的,原有的故障诊断模式行不通,而需要PaaS平台本身提供完整的预警和日志分析能力。
再次,如果发现了性能问题或故障,我们的解决方案是如何的?我们如何保证不影响到业务运行,不出现数据的丢失,或者在微服务模块扩展的时候不出现业务中断等。这些已经不是简单的部署架构层面的冗余能解决的问题,而涉及到我们在整个微服务架构中的消息策略,事务管理机制,持久化机制等问题。
微服务建设和实施中若干问题讨论
再次总结下前面讲的内容,简单来说就是两点。
其一就是企业要有明确的业务目标和需求来推动微服务转型,而不是单纯的技术驱动。其次及时有了明确需求,也需要你前期进行相应的组织,团队和技术储备和积累,建立好相应的管控机制,否则导致的是一片混乱。
当前很多人批微服务,最多的地方同样是单体拆分为微服务粒度太细,导致了大量微服务集成,接口滥用,后续无法管控和治理的问题。引入微服务本身是为了自治和解耦,结果最终实施完,你发现整个应用架构反而更加耦合了。这个不是微服务的错,而是规划和架构设计不到位的错。
下面再谈下微服务转型中常见的一些问题和实践思考。
单体应用不拆分是否就无法扩展?
单体应用存在数据库和应用两层,应用层往往容易集群扩展,而数据库是最难集群扩展的。如果数据库性能出现问题,优先要考虑的是代码和数据库层面的SQL优化(对于企业大部分应用来说性能问题不是服务器资源或能力不够,而是代码写的太烂。),其次是进行相应的读写分离或数据库拆分等。
传统单体微服务拆分颗粒度?
传统单体应用微服务拆分颗粒度为6到8个合适,这是一个毕竟粗的说法。但是传统应用本身存在流程驱动型和数据驱动型,类似OA或工单系统即流程驱动,这类应用拆分再多影响都不大,而对于数据驱动型如资产系统,那么务必注意底层共享数据层不要随便拆分,否则引入后续大量分布式事务问题。
微服务拆分和数据库拆分在我们实施总结两个概念要分开,数据库拆分后对应的上层应用模块你还可以进一步拆分为为多个独立组件,但是暂时不要去考虑独立部署。
微服务如何拆分?
微服务拆分是业务驱动而非技术驱动,需要深入地理解业务场景和业务流程,业务分析清楚后才能够明白哪些业务功能和业务数据应该聚合在一起,这样相互之间耦合性最小。不论是基于传统企业架构还是领域建模设计,核心都是基于业务驱动建模和拆分微服务。
其次微服务拆分要理解为两个层面的内容。其一是微服务模块和数据库的拆分,其二是拆分后接口的定义和识别。
是不是用了微服务框架就是微服务?
现在很多人对微服务的理解就是只要用了类似SpringCLoud等微服务框架就是微服务架构。这是很大的一个误解。微服务架构的核心在于微服务的拆分,粗粒度API接口设计,各个微服务之间的松耦合。如果这个要求没有达到不是微服务架构。
实施微服务需要哪些能力储备?
在技术上重点是对主流微服务开发框架的熟悉,其次是需要构建一个技术能力平台,实现共性技术能力下沉和共享,类似消息,缓存,4A,流程引擎,任务调度等。这些技术能力首先需要从微服务中剥离出来。只有这样微服务模块才能够将重心转移到对业务功能实现上。
在研发和过程管理上,重点是需要考虑开发团队的划分,敏捷方法论的推进,其次就是对持续集成或DevOps的过程实践。如果这些过程管理和自动化支撑工具跟不上,那么实施微服务往往带来巨大的后续实施运维工作量。
举个简单的例子,原来系统部署就一个大的WAR包,而现在变成了20个微服务模块,这个如果还依靠人工来完成显然是不现实的。
再次,微服务拆分实际和开发团队是匹配的,开发团队先拆分然后是微服务化的拆分,只有这样才能够彻底解耦。一个开发团队就2个人,一个后端开发人员管理拆分后的8个微服务模块,可以想象下这个开发人员完全无法做到按微服务边界和约束来是实现。本来该API接口调用的,反正都是自己做,又变成了直接访问数据库调用等。
为何微服务化后反而紧耦合?
这个实际是很多企业都遇到的问题,简单来说要给微服务架构的实施,如果微服务拆分后微服务间仍然没有达到解耦的目标,那么还不如不进行微服务化改造。
对于紧耦合的原因本身又体现在两点。
其一是微服务划分不合理,本来不应该拆分为2个微服务的你偏要去拆分,拆分后发现两个微服务间大量接口交互调用,自己给自己找麻烦。
其二是前期的微服务治理管控工作不到位,特别是对于微服务暴露的API接口的使用约束和标准规范等。在一个大的微服务框架下,所有的微服务共享一个服务注册中心,该微服务模块暴露的API接口完全可以被其它微服务模块访问和消费使用,也就是说微服务间的API接口访问和使用完全不受控,那么后续多个微服务间自然导致紧耦合的问题。
APM或服务链监控是否能解决服务治理问题?
再次强调下,APM或服务链监控可以帮助你改善和优化性能问题,服务调用不合理问题。但是这个已经是事后补偿操作,任何事情应该是需求和设计驱动,在一开始就避免问题,而不是出现了问题再变更和优化。
很多人观点是反正后续可以通过链路监控查看到服务链路调用关系和性能损耗等,那么在设计和开发阶段,我API接口随意调用也无所谓,这个是很错误的一个认识。包括很多人在实践微服务的时候又同时配合Scrum敏捷研发,导致微服务整个建设中完全没有架构设计工作,这本身又是一个给后期管控运维带来巨大的地雷的地方。
APM和链路监控不能没有,但是这个绝对不是你前期偷懒的理由。
高可用,高扩展和可运维
首先要认识到微服务架构下的高可用性设计往往比传统单体架构的高可用更加困难和复杂。前面谈到了拆分微服务的理由在于性能和可扩展性,以及业务能力上的解耦。
但是要注意到三者之间往往相互制约,当微服务化后性能和扩展能力确实提升,但是对于高可用性保障难度增加,对于可运维的难度增加。
很多企业在实施微服务的时候,前期在拆分的时候搞得很爽,但是后期发现拆分后的微服务太多,集成复杂度指数级上升,同时应用出现问题后连快速定位问题都难。这个也是典型的没有考虑清楚三者的均衡性问题。