微服务架构
Microservices Architecture — 从 SOA 演进而来的细粒度分布式架构
01概念与定位
通俗一点来说,微服务类似于古代著名的发明——活字印刷术,每个服务都是一个组件,通过编排组合的方式来使用,从而真正做到了独立、解耦、组件化、易维护、可复用、可替换、高可用,最终达到提高交付质量、缩短交付周期的效果。
微服务架构在五类典型架构中的位置
官方教程(第 1 章)将常用架构分为五类典型架构模型,微服务架构是其中之一:
分层架构
表现层 / 业务层 / 持久层 / 数据库,事实标准
事件驱动架构
事件队列、分发器、事件通道、事件处理器
微核架构
又称插件架构,内核 + 即插组件
★ 微服务架构
SOA 的升级,每个服务都是独立部署单元
云架构
处理单元 + 虚拟中间件,解决扩展性与并发
02SOA → 微服务演进
随着互联网技术的快速发展,为适应日益增长的用户访问量和产品的快速更新迭代,应用系统架构经历了从简到繁、从单体架构 → SOA 架构 → 微服务架构的演进过程。这导致 SOA 架构向更细粒度、更通用化程度发展,就成了所谓的微服务。
SOA 与微服务的三个本质区别
- 粒度更精细: 微服务相比于 SOA 更加精细,微服务更多地以独立的进程的方式存在,互相之间并无影响。
- 接口更通用: 微服务提供的接口方式更加通用化,例如 HTTP RESTful 方式,各种终端都可以调用,无关语言、平台限制。
- 部署去中心化: 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合。
SOA 架构:以 企业服务总线(ESB) 链接各个子系统,是集中式的技术架构;应用服务间相互依赖导致部署复杂,应用间交互使用远程通信,降低了响应速度。
微服务架构:SOA 架构的进一步优化,去除了 ESB 企业服务总线,是一个真正意义上去中心化的分布式架构。降低了微服务之间的耦合程度,不同的微服务采用不同的数据库技术,服务独立、数据源唯一,应用极易扩展和维护,同时降低了系统复杂性。
03核心特点与七大优势
微服务之所以能盛行,必然是有它独特优势的。下面分析微服务的七个方面优势:
① 技术异构性
每个服务都是独立的个体,可以选择适合自身的技术。可混合使用多种编程语言、开发框架以及数据存储技术。如社交平台用文档型数据库存帖子内容、图数据库存朋友圈关系。新技术也提供了更好的试验场。
② 弹性
弹性主要讲一部分出现故障会引起多大问题。微服务架构中每个服务可以内置可用性的解决方案与功能降级方案,比单块系统强。
③ 扩展
单块系统中要做扩展往往是整体进行扩展;而微服务架构中,可以针对单个服务进行扩展。
④ 简化部署
简单的服务更容易部署,每个服务的部署都是独立的;单个服务出问题不会导致整个系统的故障。可更快地对特定部分代码进行部署。
⑤ 与组织结构相匹配
可将架构与组织结构相匹配,避免出现过大的代码库,从而获得理想的团队大小及生产力。服务所有权也可以在团队之间迁移,从而避免异地团队的出现。
⑥ 可组合性
系统会开放很多接口供外部使用。当情况发生改变时,可以使用不同的方式构建应用;而整体化应用程序只能提供一个非常粗粒度的接口。
⑦ 对可替代性的优化
单块系统中删除上百行代码可能不知道会发生什么;但微服务架构中,可以在需要时轻易地重写服务,或者删除不再使用的服务。
从微服务架构本身延伸的特性
- 复杂应用解耦: 将单一模块应用分解为多个微服务,每个服务专注于单一功能,通过良好的接口清晰表述服务边界。由于功能单一、复杂度低,小规模开发团队完全能够掌握。
- 独立: 在系统软件生命周期中独立开发、测试及部署。当某个微服务发生变更时无需编译、部署整个系统应用;测试过程中不需要建立大范围的回归测试。
- 技术选型灵活: 技术选型是去中心化的,每个开发团队可根据业务需求发展状况选择合适的体系架构与技术。架构转型或技术栈升级时面临较低风险。
- 容错: 单体架构下某模块故障极有可能在整个应用内扩散;微服务架构下,故障会被隔离在单个服务中,系统其他微服务可通过重试、平稳退化等机制实现应用层的容错。
- 松耦合,易扩展: 传统单体架构通过将整个应用完整地复制到不同节点实现横向扩展;微服务可根据实际需求实现独立扩展。
04面临的六大挑战
"软件开发没有银弹"——微服务并不能解决所有问题,使用时面临以下挑战:
| 挑战 | 说明 |
|---|---|
| ① 分布式系统的复杂度 | 使用微服务实现分布式系统的复杂度要比单块系统高。性能方面:服务间通信通过网络,性能受影响;可靠性也会受影响;数据一致性也需要严格控制,其成本也比单块系统高。 |
| ② 运维成本 | 原来适用于单块架构的集中式部署、配置、监控或者日志收集等方式在微服务架构下,随着服务数量的增多,每个服务都需要独立的配置、部署、监控、日志收集等,因此运维成本呈指数级增长。 |
| ③ 部署自动化 | 传统部署以月、周为单位,手动部署即可;而微服务每天可能数十次甚至上百次的部署(如亚马逊),人工部署行不通,要使用自动化部署。如何有效地构建自动化部署流水线、降低部署成本、提高部署频率,是微服务架构下的挑战。 |
| ④ DevOps 与组织结构 | 传统按技能划分(开发部、测试部、运维部)并通过项目协作;微服务实施中,如何传递 DevOps 文化的价值、构建全功能团队是挑战。开发者将承担起服务整个生命周期的责任(包括部署和监控),运维越来越多表现出一种顾问式角色。 |
| ⑤ 服务间依赖测试 | 由于微服务架构是把系统拆分为若干个可独立部署的服务,所以需要进行服务间的依赖测试。在服务数量较多的情况下,如何有效保证服务之间按照接口的约定正常工作,成为必须面临的巨大挑战。 |
| ⑥ 服务间依赖管理 | 传统单块系统功能实现集中,大部分功能都运行在同一个应用中;微服务架构在功能拆分后,随着微服务个数的增多,如何清晰有效地展示服务之间的依赖关系,成为了一个挑战。 |
05微服务设计约束(4 个维度)
相较于单体应用,微服务架构在提升开发、部署等环节灵活性的同时,也提升了在运维、监控环节的复杂性。设计一个优秀的微服务系统应遵循以下设计约束:
① 微服务个体约束
- 所完成的功能在业务域划分上应是相互独立的。不同业务域有不同的技术选择权(如推荐系统用 Python 比 Java 高效)。
- 微服务对应的团队更小,开发效率也更高。"一个微服务团队一顿能吃掉两张披萨饼""一个微服务应用应当能至少两周完成一次迭代",都是对如何正确划分微服务在业务域边界的隐喻和标准。
- 微服务的"微"并不是为了微而微,而是按照问题域对单体应用做合理拆分。
- 微服务也应具备正交分解特性,在职责划分上专注于特定业务并将之做好,即 SOLID 原则中单一职责原则(SRP)。当一个微服务修改或者发布时,不应该影响到同一系统里另一个微服务的业务交互。
② 微服务与微服务之间的横向关系
- 可发现性: 当服务 A 发布和扩缩容时,依赖服务 A 的服务 B 如何在不重新发布的前提下自动感知到服务 A 的变化?需要引入第三方服务注册中心来满足服务的可发现性;对于大规模微服务集群,服务注册中心的推送和扩展能力尤为关键。
- 可交互性: 服务 A 采用什么样的方式可以调用服务 B?由于服务自治的约束,服务之间的调用需要采用与语言无关的远程调用协议(如 REST 协议很好地满足了"与语言无关"和"标准化"两个重要因素);但在高性能场景下,基于 IDL 的二进制协议可能是更好的选择。
- 需要有一个独立的元数据中心来存储服务的元数据信息。
- 面向失败设计原则尤为重要: 限流、熔断、隔仓、负载均衡等增强服务韧性的机制成为了标配。可通过协程、Rx 模型、异步调用、反压等手段进一步提升系统吞吐能力。
③ 微服务与数据层之间的纵向约束
- 数据存储隔离(DSS, Data Storage Segregation)原则: 数据是微服务的私有资产,对数据的访问都必须通过当前微服务提供的 API 来访问。否则造成数据层耦合,违背高内聚低耦合原则。
- 出于性能考虑,通常采取读写分离(CQRS)手段。
- 由于容器调度对底层设施稳定性的不可预知影响,微服务设计应当尽量遵循无状态设计原则。
- 对于有数据存取(即有状态)的微服务,通常使用计算与存储分离方式,将数据下沉到分布式存储。
④ 全局视角下的微服务分布式约束
- 从设计一开始就需考虑:高效运维整个系统,从技术上准备全自动化的 CI/CD 流水线,并支持蓝绿、金丝雀等不同发布策略。
- 面对复杂系统,全链路、实时和多维度的可观测能力成为标配。
- 需要从微服务体系多种事件源汇聚并分析相关数据,在中心化的监控系统中进行多维度展现。
- 故障发现时效性和根因精确性始终是开发运维人员的核心诉求。
06微服务六大设计模式
微服务是一种软件架构演变后的新型架构风格,是系统应用开发的一种设计思想,没有固定开发模式。开发团队可根据企业实际业务场景进行架构设计,体现了微服务架构的灵活性。常见的微服务设计模式有六种:
① 聚合器微服务设计模式
聚合器调用多个微服务实现系统应用程序所需功能,具体有两种形式:
- 将检索到的数据信息进行处理并直接展示;
- 对获取到的数据信息增加业务逻辑处理后,再进一步发布成一个新的微服务作为一个更高层次的组合微服务(从服务消费者转换成服务提供者)。
与普通微服务特性相同,聚合器微服务也有自己的缓存和数据库。
② 代理微服务设计模式
聚合器模式的一个变种。客户端并不聚合数据,只会根据实际业务需求差别选择调用具有不同功能的微服务,代理微服务器仅进行委派请求和数据转换工作。代理微服务器也有自己独立的缓存和数据库。
③ 链式微服务设计模式
客户端或服务在收到请求后,会返回一个经过合并处理的响应。例如:服务 A 收到请求后会与服务 B 建立通信,服务 B 收到请求后会与服务 C 建立通信,依次往下游发送请求,并对结果进行合并处理后作为请求响应返回上游服务调用者。
④ 分支微服务设计模式
聚合器微服务模式的一种扩展。在该模式下,客户端或服务允许同时调用两个不同的微服务链。两个微服务调用链相互独立,互不影响。
⑤ 数据共享微服务设计模式
运用微服务架构重构现有单体架构应用时,SQL 数据库反规范化可能会导致数据重复与不一致现象。按照微服务的自治设计原则,在单体架构应用到微服务架构的过渡阶段,可以使用数据共享微服务设计模式。该模式下,当服务之间存在强耦合关系时,可能存在多个微服务共享缓存与数据库存储的现象。
⑥ 异步消息传递微服务设计模式
REST 设计模式是同步的,容易造成阻塞,从而耗费大量时间。消息队列将消息写入一个消息队列中,实现业务逻辑以异步方式运行,从而加快系统响应速度。对于一些不必要以同步方式运行的业务逻辑,可以使用消息队列代替 REST 实现请求、响应,加快服务调用的响应速度。
该模式可能会降低系统可用性,并增加系统复杂性,因而在使用过程中,要做好消息队列的选型。常用消息队列有 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等。
07SOA 与微服务对比(对比记忆)
| 对比维度 | SOA | 微服务 |
|---|---|---|
| 服务粒度 | 较粗粒度,以企业为单位整合 | 更细粒度,以独立进程存在 |
| 通信机制 | 依赖 ESB 企业服务总线,集中式 | 轻量级通信(HTTP RESTful 等),去中心化 |
| 部署方式 | 服务相互依赖,部署复杂 | 分布式去中心化部署,独立部署 |
| 数据库 | 共享数据库为主 | 每个服务独立数据库,数据源唯一 |
| 耦合度 | 松耦合但服务间依赖较强 | 真正去中心化,耦合度更低 |
| 响应速度 | 远程通信降低响应速度 | 响应速度更快 |
| 适用场景 | 企业级集成,跨系统整合 | 互联网业务场景 |
08主流微服务技术框架
| 框架 | 来源 | 核心能力 |
|---|---|---|
| Apache Dubbo | 阿里巴巴 | 开源高性能 RPC 框架。特性包括基于透明接口的 RPC、智能负载均衡、自动服务注册和发现、可扩展性高、运行时流量路由与可视化的服务治理。国内使用最广泛的微服务框架。Dubbo v3 中发展服务网格(ServiceMesh),目前 Dubbo 协议已被 Envoy 支持。 |
| Spring Cloud | Pivotal | 开发者的主要微服务选择之一。提供分布式系统所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性 Token、全局锁、决策竞选、分布式会话与集群状态管理等能力。 |
| Spring Cloud Alibaba | 阿里巴巴 | 2018 年阿里巴巴陆续开源的分布式应用框架。生态包括:Nacos(注册中心 & 配置中心)、Sentinel(流控防护)、Seata(分布式事务)、Chaosblade(故障注入)。 |
| Eclipse MicroProfile | Eclipse | Java 微服务开发的基础编程模型。提供指标、API 文档、运行状况检查、容错与分布式跟踪等能力。可自由部署在任何地方(包括服务网格架构)。 |
| Tars | 腾讯 | 腾讯将其内部使用的微服务框架 TAF(Total Application Framework) 多年实践成果开源。包含一整套开发框架与管理平台,兼顾多语言、易用性、高性能与服务治理。支持 C++、Java、Golang、Node.js、PHP。 |
| SOFAStack | 蚂蚁金服 | Scalable Open Financial Architecture Stack,用于快速构建金融级分布式架构的中间件。其中 MOSN 是 Go 语言开发的服务网格数据平面代理,功能和定位类似 Envoy。 |
| DAPR | 微软 | Distributed Application Runtime, 分布式应用运行时。可移植的、无服务器的、事件驱动的运行时,可构建弹性、无状态和有状态微服务,运行在云和边缘。 |
09三种典型反模式与误区
技术往往像一把双刃剑,云原生架构演进中要根据场景选择,以下是典型反模式:
① 庞大的单体应用
最大问题在于缺乏依赖隔离,包括:
- 代码耦合带来的责任不清;
- 模块间接口缺乏治理而带来变更影响扩散;
- 不同模块间的开发进度和发布时间要求难以协调;
- 一个子模块不稳定导致整个应用都变慢;
- 扩容时只能整体扩容而不能对达到瓶颈的模块单独扩容。
应对: 当业务模块可能存在多人开发的时候,就需要考虑通过服务化进行一定的拆分,梳理聚合根,通过业务关系确定主要的服务模块以及这些模块的边界,清晰定义模块之间的接口,并让组织关系和架构关系匹配。
② 单体应用"硬拆"为微服务
服务的拆分需要适度,过分服务化拆分反而会导致新架构与组织能力的不匹配:
- 小规模软件的服务拆分: 软件规模不大、团队人数也少,强行把耦合度高、代码量少的模块进行服务化拆分,一次性发布需要拆分为多个模块分开发布维护。
- 数据依赖: 服务虽然拆分为多个,但是数据是紧密耦合的,让这些服务共享数据库,造成服务间数据依赖。
- 性能降低: 耦合性很强的模块被拆分为多个微服务后,原来的本地调用变成了分布式调用,响应时间变大了上千倍,整个服务链路性能急剧下降。
③ 缺乏自动化能力的微服务
当软件规模变大后,自动化能力的缺失会带来严重危害:
- 接口增多带来测试用例增加,更多模块排队等待测试和发布;
- 缺乏自动化造成软件发布时间变长;
- 多环境发布或异地发布时需要专家处理环境差异;
- 缺乏自动化的人工运维容易给环境带来不可重现的影响;
- 发生人为运维错误不容易"快速止血",故障处理时间变长。
结果导致:软件交付时间变长、风险提升以及运维成本的增加。
10考点速记卡
微服务核心特点四要素:小专一、轻通信、松耦合、独部署
异 · 弹 · 扩 · 部 · 组 · 合 · 替
技术异构 / 弹性 / 扩展 / 简化部署 / 与组织结构匹配 / 可组合 / 对可替代性的优化
复 · 运 · 部 · D · 测 · 依
分布式复杂度 / 运维成本 / 部署自动化 / DevOps 与组织 / 服务间依赖测试 / 服务间依赖管理
聚 · 代 · 链 · 分 · 数 · 异
聚合器 / 代理 / 链式 / 分支 / 数据共享 / 异步消息传递
个 · 横 · 纵 · 全
个体约束 / 横向关系(服务发现+服务调用) / 纵向约束(DSS+CQRS+无状态) / 全局分布式(CI/CD+可观测)
- SOA 集中式(ESB),微服务去中心化 —— 这是两者最本质的区别
- SRP(单一职责原则)—— 微服务个体约束的核心
- DSS(数据存储隔离)—— 数据是微服务的私有资产
- CQRS(读写分离)—— 性能考虑下的纵向约束
- 链式微服务采用同步,消息传递模式采用异步
- 常用消息队列: ActiveMQ、RabbitMQ、RocketMQ、Kafka