无代理服务网格
1. 什么是无代理服务网格 (Proxyless Service-Mesh) ?
1.1 服务网格简介
Istio 是当今最流行的开源服务网格。它由控制平面和数据平面组成。其架构如下。图片取自 istio 官网
位于图下半部分的控制平面负责配置、服务信息和证书等资源的交付。位于上部的数据平面关注服务之间的通信流量;传统服务网格通过代理拦截所有业务网络流量,代理需要感知控制平面下发的配置资源,从而按需控制网络流量走向。
在 Istiod 环境中,其控制平面是一个名为 istiod 的进程,网络代理是 envoy。istiod 通过监听 Service 和 Endpoint 等 K8S 资源获取服务信息,并通过 XDS 协议将这些资源发送给数据平面上的网络代理。Envoy 是一个独立进程,以 sidecar(边车)的形式与业务应用 Pod 一起运行。它与应用进程共享同一个主机网络,并通过修改路由表劫持业务应用的网络流量。
服务网格可以解决微服务场景下的很多问题。随着集群规模的扩大和业务复杂度的增长,基于原生 k8s 的容器编排方案将难以应对,开发者不得不面对巨大的服务治理挑战。服务网格很好地解决了这个问题。它将服务治理需求封装在控制平面和代理中,业务开发者只需关注业务逻辑。应用部署后,运维人员只需修改配置即可实现故障恢复、负载均衡、灰度发布等功能,大大提高了研发和迭代效率。
Istio 的 sidecar 通过容器注入的方式伴随业务应用进程的整个生命周期,对业务应用无侵入性,解决了业务应用迁移、多语言、基础设施耦合等问题。但这也带来了资源消耗高、请求延迟增加的问题。
服务为服务治理提供了一个很好的思路,将基础设施与业务逻辑解耦,使应用程序开发人员只需关注业务。另一方面,由于 sidecar 的缺点,我们可以考虑使用 sdk 代替 sidecar 来支持数据平面。
1.2 无代理服务网格
无代理服务网格是近年来提出的一个新概念。istio、gRPC、brpc 等开源社区都在朝着这个方向进行探索和实践。无代理服务网格框架以 SDK 的形式被业务应用引入,负责服务之间的通信和治理。来自控制平面的配置直接发送到服务框架,服务框架取代了上述 sidecar 的功能。
服务框架(SDK)的主要功能可以概括为以下三点
- 连接到控制平面并监控配置资源。
- 对接应用,为开发者提供便捷的接口。
- 连接网络,根据资源变化响应流量规则。
1.3 无代理的优缺点
优点
- 性能:无代理模式下的网络调用是点对点的直接通信,网络延迟比代理模式小很多。
- 稳定性:无代理模式是单进程,拓扑结构简单,易于调试,稳定性高。
- 框架集成:市面上已经有许多 sdk 模式的服务框架,切换到 mesh 后,具备复用框架的能力
- 资源消耗:无 sidecar,资源消耗低
缺点
- 语言绑定:需要用多种语言开发 sdk
- 可移植性低:无法通过切换 sidecar 的形式非侵入式地升级基础设施。
总的来说,Proxyless 架构由于其高性能和高稳定性,更适合在生产环境中使用。
2. Dubbo-go 和无代理服务网格
2.1 Dubbo-go 在无代理服务网格场景下的设计
服务注册发现
Dubbo-go 本身具有可扩展的服务注册和发现能力,我们针对服务网格场景适配了注册中心的实现。开发者可以在 istiod 控制平面上注册 dubbo-go 应用信息。客户端应用可以查询注册的接口数据完成服务发现过程。
- 开发者使用 dubbogo-cli 工具创建应用模板并将 Deployment / Service 发布到集群。
- 服务器拉取全量 CDS 和 EDS,比较本地 IP,获取当前应用的主机名。并在 Istiod 上注册该应用的所有接口名到主机名的映射。
- 客户端从 istiod 拉取全接口名称到主机名的映射关系,并将其缓存在本地。当需要发起调用时,会查询本地缓存,将接口名称转换为主机名,再通过 CDS 和 EDS 拉取到当前集群对应的完整端点。
- 所有端点都会经过 Dubbo-go 内置的 Mesh Router,过滤出最终的端点子集,并根据配置的负载均衡策略发起请求。
开发者在整个过程中只需要关注接口,完全不需要关心主机名和端口信息。即服务端开发者只需要实现 pb 接口并使用框架暴露即可;客户端开发者只需要引入 pb 接口并直接发起调用即可。
流量管理
Dubbo-go 具备路由能力,通过 xds 协议客户端订阅 istiod 的路由配置,实时更新到本地路由规则,从而实现服务治理。Dubbo-go 兼容 istio 生态的流量治理规则,通过配置 Virtual Service 和 Destination Rule,可以将打标的流量路由到指定的子集,也能更深入地应用于灰度发布、流量切换等场景。
云原生脚手架
dubbogo-cli 是 Apache/dubbo-go 生态的子项目,为开发者提供了应用模板创建、工具安装、接口调试等便捷功能,提升用户研发效率。
详情请参考 [dubbogo-cli 工具]
3. Dubbo-go-Mesh 的优势
3.1 接口级服务发现
前文介绍了通过接口级服务注册进行发现的优势,即开发者不需要关心下游主机名和端口号,只需要引入接口存根,或者实现接口,并通过框架启动即可。
3.2 高性能
我们在 k8s 集群中部署了 istio 环境,分别测试了 sidecar 模式的 gRPC 服务调用和 Proxyless 模式的 dubbo-go 应用服务调用。发现 Proxyless 模式在请求耗时方面比 sidecar 模式低一个数量级,即性能提升约十倍。
3.3 跨生态
Dubbo-go 是一个跨越多个生态的服务框架。
Mesh 生态
开发者可以在使用 Dubbo-go 进行应用开发的同时,利用 istio 生态提供的强大能力。
gRPC 生态
- Dubbo-go 支持与 gRPC 服务互操作,支持 HTTP2 协议栈。
- Dubbo-go 默认使用 pb 序列化,性能高。
Dubbo 生态
- 多语言优势,可以实现 Go-Java 应用互通。
- 兼容 pixiu 网关,便于服务暴露和协议转换。
- 使用 Dubbo-go 生态组件。