1 架构的发展历程
聊微服务架构前,先来简单说说架构的发展历程:经历“单体架构->分布式架构->SOA架构->微服务架构”的发展。
单体架构:将所有的功能模块都打包到一个应用程序包中,并部署在一个应用服务器上。这种架构的优点就是简单易用,开发、测试、部署都比较方便,适合于业务简单的小型项目或项目早期阶段;缺点是可扩展性和可靠性比较差,随着业务的发展越来越难满足需求,某一个功能引发的异常会导致整个系统不可用。但单体架构也仍然有适用的场景,例如,基于业务中台为前端业务场景开发的buffer层,主要做接口的逻辑封装,目的是简化前端逻辑,就比较适合使用单体架构。
分布式架构:采用“分而治之”的思想,将系统划分为多个业务模块,将这些业务模块分别打包到不同的应用程序中,部署到不同的应用服务器上,模块间采用接口的方式进行交互。这种做法让系统具有更好的可扩展性和可靠性,新业务模块的研发可以独立打包和部署,对原有业务模块不影响;单个模块的异常不会影响整个系统的可用性。同时,也可以更好地利用服务器的资源,提升系统的性能。后续发展出来的SOA架构和微服务架构也都是分布式架构。
SOA架构:SOA是一种面向服务的架构,基于分布式的设计理念,引入服务化的思维,将业务模块独立成服务,所有服务都注册到ESB(企业级服务总线),服务间的接口调用通过ESB来进行转发。SOA中的服务接口是企业的IT资产,需要做到标准化、高内聚、低耦合、可重用等。通过标准化的服务接口来实现系统的松耦合交互。SOA是一种“中心化”的设计,将其应用在互联网电商的高并发业务场景可能出现“雪崩”反应。
微服务架构:是SOA设计思想的延续,一种更彻底的面向服务的架构。将原有系统按业务职责划分为独立的小应用,每个小应用的职责要单一,每个小应用可以独立开发、设计、运行和运维,每个小应用的开发架构也可以是相互独立的(例如,A1应用采用Java开发,A2应用采用C++开发,A3应用采用python开发)。将一个小应用成为一个微服务。微服务之间采用约定的协议进行通信,可以是基于 HTTP 的 RESTful API,也可以是私有协议。微服务架构常被认为是一种去“中心化”的设计,但在实际使用中,前端对微服务的访问地址是透明的,也需要做统一的接口拦截、服务限流熔断、安全认证等,会通过API网关访问微服务应用,所以,整个架构并不是一个完全意义上的“去中心化”架构,只能做到微服务内部治理的“去中心化”。
2 微服务架构
微服务架构设计可以划分为两部分:
-
第一部分是微服务架构的技术底座,主要包括服务注册、负载均衡、远程调用、服务限流熔断降级、网关、消息、缓存等技术组件的选型或自主设计;
-
第二部分是微服务的划分,包括服务的界定和服务间的关系等。微服务划分是微服务系统建设的重点和难点。
2.1 微服务架构的优势和挑战
2.1.1 微服务架构优势
围绕微服务技术底座构建的微服务架构,具有以下优势:
-
可扩展性:微服务系统按照业务职责进行服务划分,可以按业务需求进行服务的独立扩展,而不需要对整个系统进行调整;
-
技术灵活性:微服务之间采用约定的协议进行通信,每个服务可以采用相互独立的开发架构。服务A1对实时性要求比较高,可以采用C++开发;服务A2重点是数据的分析和统计,可以采用python开发;服务A3作为管理系统,可以采用Java开发;
-
敏捷性:微服务系统按照业务职责划分成各自独立的服务后,每个服务的业务职责变得单一和内聚,可以更快地进行迭代和升级;
-
故障隔离:微服务系统拆分成多个服务后,单个服务的故障,不影响整个系统的可用性。
2.1.2 微服务架构挑战
微服务系统按照业务职责拆分成多个服务后,系统变得更加复杂,也带来不少挑战:
-
数据一致性:每个服务有独立的数据库,相互之间隔离,给数据的一致性带来挑战。例如,网购一个商品至少涉及到订单、支付、库存等多个微服务的调用,要保证所有服务都执行成功,确保最终的数据正常。数据一致性分强一致性和最终一致性,强一致性可以采取两阶段提交协议(2PC)、XA协议等方案,XA协议对数据库选型有要求,两阶段提交协议带来额外的开发成本;最终一致性可以采取TCC补偿事务、Saga事务模型、基于消息队列的最终一致性等方案。需根据具体的业务场景确定数据一致的方案;
-
问题难排查:微服务内部“去中心化”后,微服务间的通信是点对点的调用,会发现微服务的调用最后形成了一个网状结构,造成问题非常难以排查。构建微服务架构时,需要将全链路日志的采集、分析和监控的建设纳入到规划中;
-
运维复杂性:系统拆分成多个微服务后,增加了运维的成本,需要管理多个服务的部署、监控等。构建微服务架构时,也应该将自动化运维的建设纳入到规划中;
-
测试复杂性:测试复杂性随着服务间依赖关系的增加而上升,需要进行端到端的功能连通测试。需要逐步构建自动化测试流程;
-
沟通成本:微服务系统按照业务职责拆分成多个服务后,每个服务的专注于界定的业务职责,团队间的需求商定、方案商定、联调测试、发版计划、部署计划、上线计划等沟通和协调的成本会上升。
2.2 微服务实践原则
为充分利用微服务架构的优势和应对微服务的挑战,微服务实践应遵循一定的原则:
-
职责单一原则:每个微服务的业务职责明确且唯一,但并不是按功能维度划分得越细越好,而是按业务职责进行归类。例如,通知中心的定位是向客户发送消息,可以包含短信通知、邮箱通知、微信通知等,不需要为每种通知类型构建一个微服务。因为微服务拆分得越细,运维、沟通等成本越高。笔者见过有的系统前期微服务拆得非常细,到客户现场后部署复杂导致实施周期非常长,遇到问题发现调用的链路太长,排查问题需要协调各方资源,经过很长时间后才能定位问题,最后不得不做微服务的合并;
-
内部资源独立:每个微服务的资源需要独立,不能相互间共享,包括运行配置、缓存、表结构、数据库等。微服务间的资源共享,可能会造成微服务的耦合,会,出现共享资源的变更导致多个微服务必须同时升级;
-
接口定义粗颗粒度:微服务的接口应该是粗颗粒度的。接口是服务间的边界,如果接口越多,那么服务间的依赖耦合越高。所以,接口的定义应该是粗颗粒度的,增加接口的可复用性,减少服务间的依赖耦合。但也不是把完全不相关的功能都包装到一个接口里面,应该是将同个业务的不同种类的功能包装到同个接口;
-
接口要向下兼容:接口要做到向下兼容,做到高内聚低耦合。服务间的交互都是通过接口调用来实现的,不能出现上游的接口修改,下游的业务实现逻辑也必须跟着调整,会导致服务间形成强依赖强耦合;
-
控制单个微服务的开发人数:基于康威定律,系统架构反应了团队的组织结构。微服务架构是将系统按业务职责拆分成多个微服务,如果单个微服务的开发人数过多,那么说明这个微服务承担的业务职责过大,不利于系统快速迭代,也没有达到业务的解耦的目的,可以考虑进一步做服务拆分。参考敏捷Scrum的人数要求,建议单个微服务的开发人数不要超过10人;
-
根据质量要求拆分微服务:每个微服务都会有各自的核心质量要求,例如高性能、高可用、快速迭代等,对于核心质量要求差异比较大的功能,需要拆分到不同的微服务中。
以上枚举了微服务拆分和管理的一些通用原则,还应该在实际工作中按照具体的业务场景不断完善微服务的实践原则。如果违背这些原则,会付出对应的成本来解决带来的问题。
总结
微服务架构为复杂且快速迭代的业务场景提供了较好的解决方案,带来系统的优势,同时也让系统设计面临新的挑战,可以按业务实际需求设定一定的实践原则来规避或降低解决这些挑战的成本。