01 背景
随着 Docker 和 Kubernetes 的出现,一个庞大的单体应用可以被拆分成多个独立部署的微服务,并被打包运行于对应的容器中。不同应用之间相互通信,以共同完成某一功能模块。微服务架构与容器化部署带来的好处是显而易见的,它降低了服务间的耦合性,利于开发和维护,能更有效地利用计算资源。当然,微服务架构也存在相应的缺点:
- 强依赖于SDK,业务模块与治理模块耦合较为严重。除了相关依赖,往往还需要在业务代码中嵌入SDK代码或配置。
- 统一治理难。每次框架升级都需要修改 SDK 版本,并重新进行回归测试,确认功能正常后再对每一台机器重新部署上线。不同服务引用的 SDK 版本不统一、能力参差不齐,增大了统一治理的难度。
- 缺少一套统一解决方案。目前市场不存在一整套功能完善、无死角的微服务治理与解决方案。在实际生产环境往往还需要引入多个治理组件来完成像灰度发布、故障注入等功能。
为解决这些痛点,Service Mesh诞生了。以经典的side car模式为例,它通过在业务 Pod 中注入 Sidecar 容器,对代理流量实施治理和管控,将框架的治理能力下层到 side car 容器中,与业务系统解耦,从而轻松实现多语言、多协议的统一流量管控、监控等需求。通过剥离 SDK 能力并拆解为独立进程,从而解决了强依赖于 SDK 的问题,从而使开发人员可以更加专注于业务本身,实现了基础框架能力的下沉,如下图所示(源自dubbo官网):
经典的 Sidecar Mesh 部署架构有很多优势,如减少 SDK 耦合、业务侵入小等,但增加了一层代理,也带来了一些额外的问题,比如:
- SideCar 代理会损耗一部分性能,当网络结构层级比较复杂时尤其明显,对性能要求很高的业务造成了一定的困扰。
- 架构更加复杂,对运维人员要求高。
- 对部署环境有一定的要求,需要其能支持SideCar代理的运行。
为解决这些痛点,Proxyless Service Mesh 模式诞生了。传统服务网格通过代理的方式拦截所有的业务网络流量,代理需要感知到控制平面下发的配置资源,从而按照要求控制网络流量的走向。以istio为例,Proxyless 模式是指应用直接与负责控制平面的istiod进程通信,istiod进程通过监听并获取k8s的资源,例如Service、Endpoint等,并将这些资源统一通过 xds 协议下发到不同的rpc框架,由rpc框架进行请求转发,从而实现服务发现和服务治理等能力。
Dubbo社区是国内最早开始对Proxyless Service Mesh模式进行探索的社区,这是由于相比于 Service Mesh,Proxyless模式落地成本较低,对于中小企业来说是一个较好的选择。Dubbo 在3.1 版本中通过对xds协议进行解析,新增了对 Proxyless 的支持。Xds是一类发现服务的总称,应用通过xds api可以动态获取Listener(监听器),Route(路由), Cluster(集群), Endpoint(集群成员)以及Secret(证书)配置。
通过 Proxyless 模式,Dubbo 与 Control Plane直接建立通信,进而实现控制面对流量管控、服务治理、可观测性、安全等的统一管控,从而规避 Sidecar 模式带来的性能损耗与部署架构复杂性。
02 Dubbo Xds 推送机制详解
@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black
' hide footbox 可关闭时序图下面部分的模块
' autoactivate on 是否自动激活
skinparam sequence {
ArrowColor black
LifeLineBorderColor black