微服务治理技术白皮书重磅发布
——肖京
阿里云智能技术专家、Spring Cloud Alibaba发起人
《微服务治理技术白皮书》主编
在微服务大行其道的今天,大家越来越认同业务的生产落地离不开微服务的维护。但是业内对微服务的认知却是五花八门各不相同,未曾统一标准和共识。
历经半年多筹备,《微服务治理技术白皮书》终于在 2022 年 4 月 13 日面世,它是业内首本聚焦于微服务治理业务领域的白皮书。我们希望通过这本书能够对高效解决原生架构下微服务治理难题起到些许作用。
白皮书不仅包含了阿里巴巴电商体系十余年的微服务治理经验,同时也吸收了很多阿里云微服引擎 MSE 的产品服务于各行各业云上客户所沉淀下来的经验,可以说是一本集大成者的书。
不同于一些仅聚焦于微服务治理技术原理的书籍,白皮书还囊括了业务场景、解决方案、最佳实践等微服务落地全流程。它不仅是一本深度分析微服务治理的技术书,更是一本解决微服务落地生产相关难题的书,因此非常推荐从事微服务领域开发、运维、测试、稳定性以及产品设计相关人员阅读。
一、全书目录导读
全书分为五章。
第一章主要介绍了微服务治理技术概念,通过一家企业的 IT 发展历程阐述了微服务治理的必要性,同时也分析了微服务在云原生时代下发展的趋势和新挑战。
第二章主要介绍了微服务治理底层的技术发展和变迁,详细阐述了微服务治理如何向透明化和业务无侵入方向发展。
第三章主要整理和归纳了微服务架构中常见的痛点场景,出现痛点场景的原因以及出现之后的影响,再深入分析可以通过哪些技术方案解决这些问题,最后详细介绍该解决方案下底层的技术实现。
第四章和第五章主要基于阿里云微服务引擎MSE 产品的云上客户解决微服务治理技术难题时的最佳实践以及一些标杆客户案例分享。
上图为阿里巴巴集团内部微服治理技术的演进历程。
微服务治理技术发展之处,阿里使用独立开发的各种中间件 SDK 的方案推进微服务。此阶段最突出的问题是各种 SDK 依赖冲突非常严重,甚至会出现因为依赖冲突而导致应用无法启动。此外,SDK 需要在业务代码里引入,出现依赖冲突问题时需要升级 SDK ,而升级成本非常高。
2013年左右,阿里使用潘多拉轻量级容器实现内隔离和内导出,解决了依赖冲突问题,提升了运维和治理效率。使用潘多拉之后,中间件代码不再直接由业务开发包引入,而是从潘多拉容器里导出,业务代码只需要引入空实现 SDK 即可引入中间件逻辑。一些小变更只需直接升级潘多拉版本即可。但是中间件出现重大升级时,依然需要升级 SDK ,同样也需要修改代码逻辑,会影响开发和运维流程。
2019 年,阿里推出了基于One Java Agent 的微服务治理技术,将微服务治理的自建逻辑置于Java Agent中,在应用运行时可动态修改微服务框架关键类的字节码,实现了微服务治理逻辑和业务开发完全隔开,无需修改任何业务代码,即能享受完整的微服务治理技术。
将微服务治理下沉到 Java Agent 后,能够实现应用开发时无需感知微服治理技术,只需使用开源框架标准用法,比如 Spring Cloud 来开发应用。在运行时,挂载上 Java Agent 即可直接实现微服务治理。
挂上 Java Agent 后,可在加载过程中动态地修改框架关键字节码,比如服务注册、服务发现、路由选址、负载均衡等关键过程。举个例子,在服务注册时可加上一些额外信息,或在服务路由时将流量特征和路由规则进行比对,通过这些方式来实现微服务治理的功能。
同时 Java Agent 还可以通过上报数据的方式动态获取服务治理规则,或上报一些metrics 关键应用事件等信息,从而实现无损下线、离群实例摘除、限流降级、服务鉴权等一系列治理逻辑。
One on Java Agent 项目已经开源,用户可以登录 github ,在阿里巴巴 group 下找到本项目了解更多详情。
微服务生产落地离不开微服治理的保驾护航。围绕云原生下的微服务趋势,我们认为微服务治理应该更加专注于提升开发迭代效率以及增强稳定性。其中增强稳定性包括变更时的稳定性、偶发异常下的稳定性以及业务安全。据统计,90%以上的线上故障都由变更引起。
即使在业务代码没有任何问题的情况下,发布过程中依然有可能出现业务报错。无损下线就是非常典型的场景之一。
在微服务框架中,服务提供者从开始下线到消费者最终感知到节点已经下线而不再发起调用,存在时间差,极端情况下可达 90 秒。
而在这 90 秒的过程中,服务消费者会持续不断地调用已经下线的节点,导致业务出现报错,这也是大多数开发者通常选择在半夜发布的原因。
《微服治理技术白皮书》推荐的解决方案中提供了一个 offline 命令,可以在真正停止之前执行offline 命令。服务提供者收到 offline 命令之后,首先会提前去注册中心将自己注销,然后跨过注册中心直接点对点地通知服务消费者:已经进入下线流程,需要尽快刷新消费者列表,从而实现了无损下线中非常关键的一点,即尽早摘除所有流量。
此外,如何确保在途请求都能处理完毕,主要通过ShutdownHook 方式进行智能等待。如果请求没有处理完,则在停止之前需要等待更长时间,等所有在途请求都处理完毕且已经返回,才会进入真正的销毁流程。
通过无损下线方式,可以博阿正发布过程中老应用节点在停止过程中不会影响业务。
上线和下线在发布过程中是连贯的动作,上线过程中也存在很多问题。比如Redis 连接池或数据库连接池刚启动时,连接还未建立好而流量已经到达,则会出现影响业务的报错。
而无损上线的解决方案,能够提前将数据库连接池、Redis 连接池通过 Java Agent 技术进行扫描,提前进行预建连接,从而避免上述情况。
流量打过来时产生报错,无法找到报错原因,该如何解决?可以通过小流量预热功能。通过 Java Agent 技术对新起来的 Pod 服务权重进行调节,新应用权重较小,经过一段时间预热后,才会达到与老节点同样的比重。因而可以选择流量曲线,比如二次曲线,从而实现小流量预热方式。
小流量预热是一个比较通用的方案,比如连接池或 Java 没有开启并行内加载导致延迟,或JVM 本身 git 编译优化流程,都可以通过此方式来解决。
k8s readiness 检查和微服务框架的readiness 默认情况下并没有打通。举个例子,如果没有配置 k8 readiness,可能进程启动之后认为已经 ready ,会进行滚动发布,直接进入下一批。但此时微服务并没有启动成功,意味着新起节点还没有注册到注册中心,老节点就已经被停掉,会导致注册中心没有任何服务提供的节点存在。
因此,需要将 k8s readiness 和微服务 readiness 进行打通。而微服务readiness 打通是非常复杂的流程,涉及服务有没有到注册中心,需要自己写readiness 健康检查是否可行,以及服务有没有预热完毕等。
针对上述问题,《微服治理技术白皮书》的推荐方案是通过 Java Agent 技术实现一个 controller ,其逻辑是自动动检测原有readiness 接口是否已经就绪、服务是否已经注册到注册中心、 tomcat 或Dubbo 服务提供者的端口是否已经在监听状态,同时也会与服务预热状态挂钩,以此实现无损上限。
在无损上线和无损下线相结合解决了一个问题,即如果新发布的代码没有问题,则发布过程不会因为应用停止或启动而出现任何问题,即使白天发布也几乎不会对用户体验产生影响。
然而现实是残酷的,没有人能百分百保证代码没有任何问题,新发布的业务代码中存在一些逻辑异常是常态。假设应用有四个节点,发布其中一个节点,出现问题则会对业务25% 的流量产生影响,甚至有可能直接影响 25%的用户,影响面非常广。
可以借助全链路灰度解决方案,控制新版本发布时的影响面。本文以云原生时代 k8s 部署新应用为例详解其过程:
在发布新版本时,给新版本打上版本标签。微服务提供者会将其版本标签直接注册到注册中心中。服务消费者获取服务提供列表时,不仅可以直接从注册中心获取 IP 和端口,还可以获取到这些 IP 和端口对应的服务提供者。
结合 Java Agent 技术,可以通过治理中心配置下发的方式获取到灰度规则。举个例子, http 请求的 header 里是 userID 字段,除以 100 余 20 的用户才能够知道新版本,这意味着使用特殊的方式引入 1% 流量进来,且这 1% 流量是固定的。
因此,如果没有配置规则,则不会有任何流量到达新版本,只有配置了规则并且规则是打开的情况下,符合规则的流量才会路由到新版本。这意味着新版本发布流量是非常可控的,比如可以设置为只有内部用户才会被路由到新版本。发布的时候可以做非常灵活的验证,如果验证不通过,只需简单地将路由规则关闭,就不会有任何流量到达灰度版本,所有流量都会被路由到稳定的基线版本;如果验证成功,即可将原先稳定的 deployment 换成新版本镜像。
总结来说,只要不配规则,新版本即不会影响任何用户;如果发现规则有问题,影响了部分用户,只需将规则关闭,所有用户即可回到正常的稳定版本流量中。
灰度发布的最佳实践如下:最初,规则配置为内部用户才能访问到新版本;内部用户验证通过后,可以对规则进行修改,引入固定的 1% 用户流量进来验证;如果验证通过,则可根据业务需要决定是继续扩大灰度范围,也可直接进行全量发布。发布新版本只会影响内部用户,后续可逐步扩大流量,出现任何问题都能够实现秒级回滚,即使在白天也可以放心发布。
结合全链路灰度和无损上下线两个方案,可以基本消除变更过程中的稳定性风险。
此外,如果存在多个应用A、B、C,调用链从网关过来再到 A 、 B 、 C,则灰度流量不止要进入 A 的灰度版本,流量到达 B 和 C 时也应该去灰度版本。如果 B 没有进行灰度,只有稳定版本,A 的灰度流量先去 B 的稳定版本,但下一跳依然会到达 C 的灰度版本,这才是全链路的解决方案。
全链路是非常基础的技术,除了适用于发布中的全链路灰度化,也适用于其他场景,比如开发/测试环境隔离、全链路压测。
在敏捷开发过程中,一个迭代中可能存在多个不同团队、多个功能并行开发,因而不可避免地会出现抢环境的情况。如何解决这个问题?
最简单方式当然是各自都有一套完全独立的环境,即物理隔离,但物理隔离成本非常高。如果结合全链路灰度应用,即可实现逻辑上的隔离,可以以非常低成本的方式,让每一个开发人员都有一套属于自己的独立环境。
此外,直接使用线上环境进行压测的风险非常高。如果用测试环境进行压测,由于测试环境与生产环境存在区别,结果可能会存在较大偏差。
可以通过全链路压测结合全链路灰度的方式,让压测流量到数据库影子表, Redis 落到影子 key,消息落到影子 topic,以此实现直接使用线上环境做压测,而且非常安全,不仅实现了零机器成本和零维护成本,而且结果真实有效。
全链路不仅包括扩数据库、缓存消息、前端、网关、分布式任务调度,还需要有完整的配套设施,比如规则配置、规则同步、秒级可观测能力以及流控大盘,将以上方式完整地整合在一起,才是真正的全链路解决方案。
《微服治理技术白皮书》于 4 月 13 日发布之后,短短两个月内下载量已突破 1 万,这是开发者对这本电子书质量的认可,也让我们有更多动力去提供更好的阅读体验。
《微服治理技术白皮书》书研读班和音频版也已正式发布。通过《微服治理技术白皮书》研读班,可以以线上训练营的方式分步骤按重点进行打卡,利用碎片化时间参与办学,与同学们共同讨论,共同成长。训练营结束后还将颁发阿里云官方结业证书。
除了阅读电子书之外,我们还联合喜马拉雅对《微服治理技术白皮书》进行有声化运营,推出了白皮书音频版,读者可以以更沉浸的方式去学习微服务技术。










