Spring Cloud 应用 Proxyless Mesh 模式探索与实践时间:2022-12-20 14:05:30*作者:十眠* ## Service Mesh 简介 Service Mesh 早已不是一个新兴的概念,目前已经有许多关于 Service Mesh 的探索以及实践。 - 2016 年可以说是 Service Mesh 的元年,Buoyant 公司 CEO William Morgan 率先发布 Linkerd ,成为业界首个 Service Mesh 项目,同年 Lyft 发布 Envoy ,成为第二个 Service Mesh 项目。 - 2017年,Google、IBM、Lyft 联手发布了 Istio,它与 Linkerd / Envoy 等项目相比,它首次给大家增加了控制平面的概念,提供了强大的流量控制能力。经过多年的发展 Istio,已经逐步成为控制平面的事实标准。 - 1.0 版本的问世标志着 Istio 进入了可以生产可用的时代,越来越多的企业将服务网格应用于生产中。 - 1.5 版本开始将原有的多个组件整合为一个单体结构 istiod;同时废弃了被诟病已久的 Mixer 组件,统一为 Istiod 服务,方便部署和运维。 在目前看来 Istio 是最流行的开源服务网格,它由控制平面和数据平面两部分构成。 ![1.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/08a6882e96b64d4693a7630152c6ae87~tplv-k3u1fbpfcp-zoom-1.image "1.png") 在 Istio Mesh 架构中,其控制平面是一个名为 Istiod 的进程,网络代理是 Envoy 。Istiod 作为控制面的统一组件,负责对接服务注册发现、路由规则管理、证书管理等能力,Envoy 则是作为数据面通过 Sidecar 方式代理业务流量,Istio 和 Envoy 之间通过 XDS 协议接口完成服务发现、路由规则等数据的传递。Istiod 通过监听 K8S 资源例如 Service、Endpoint 等,获取服务信息,并将这些资源统一通过 xDS 协议下发给位于数据平面的网络代理。Envoy 则是独立于应用之外的一个进程,以 Sidecar 的方式(一般是以 Container 方式)伴随业务应用 Pod 运行,他与应用进程共用同一个主机网络,通过修改路由表的方式劫持业务应用的网络流量。 > xDS 协议接口详见 xDS REST and gRPC protocol 文档 **[** **1]** 随着集群规模的扩大与业务复杂度的增长,基于原生 k8s 的容器编排方案将会难以应付,开发人员不得不面对巨大的服务治理挑战。Service Mesh 可以很好地解决了这一问题,它将服务治理能力封装在了控制平面与代理中,业务开发人员只需要关注于业务逻辑本身。在应用部署之后,只需要运维人员通过修改配置,即可实现诸多服务治理能力,例如故障恢复、负载均衡、灰度发布等,这极大地提高了研发和迭代效率。 Istio 的 Sidecar 通过容器注入的形式伴随业务应用进程的整个生命周期,对于业务应用是毫无侵入的,这解决了业务应用可迁移、多语言、基础架构耦合等问题。但这也带来了高资源消耗、请求时延增长的问题。考虑到 Sidecar 的弊端,我们可以考虑使用 SDK 的形式,来替代 Sidecar 支撑起数据平面,那么就引出了 Proxyless Mesh 的架构。 ## Proxyless Service-Mesh 什么是 Proxyless Service-Mesh (无代理服务网格)?这是近几年提出的一个新的概念,isito、gRPC、brpc 等开源社区都在这一方向进行了探索和实践。无代理服务网格框架以 SDK 的形式被业务应用引入,负责服务之间的通信、治理。 ![2.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/50d60fc15b8349348431cf7aa0b2e440~tplv-k3u1fbpfcp-zoom-1.image "2.png") ### gRPC Proxyless 架构 目前 gRPC 项目对 xDS API 协议提供了一定的支持,也就是说我们可以通过 istio 管理 gRPC 服务,并且不需要部署 Envoy sidecar。 ![3.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/137c0d9b8ff64c259c550c01faf491f0~tplv-k3u1fbpfcp-zoom-1.image "3.png") 如上图所示 gRPC Proxyless 模式需要 Istio Agent 来进行初始化以及与控制面的通信。首先,Istio Agent 在启动时生成一个引导文件,这和为 Envoy 生成引导文件的方式相同。它用来告诉 gRPC 库如何连接到 istiod,在哪里可以找到数据面通信的证书,以及向控制面发送什么元数据。接下来,Istio Agent 作为一个 xDS proxy,代表应用程序与 istiod 进行连接和认证。最后,Istio Agent 获取并轮换数据平面通信中使用的证书。 > 详见 gRPC Proxyless Mesh 文档 **[2** **]** ### 浅谈 Proxyless 架构的优缺点 简单整理了一下 Proxyless Mesh 架构的一些优缺点 Proxyless Mesh的优点: - 性能:无代理模式的网络调用为点对点的直接通信,网络时延会比代理模式小很多。 - 稳定性:Proxyless 的模式是单进程,拓扑简单,便于调试,稳定性高。 - 成本:没有 sidecar,资源消耗低。 - 框架集成:市面上已有众多 SDK 模式的服务框架,切换至 Mesh 后依旧可以复用框架原有的能力 Proxyless Mesh的缺点: - 框架、语言绑定:需要开发多种语言、框架的 SDK 支持 Proxyless Mesh 能力,目前市面上不少框架还未支持 Proxyless Mesh的能力。 - 可迁移性低:无法通过切换 Sidecar 的形式来无侵入地升级基础设施,需要修改代码进行升级与维护。 Proxyless 架构的优点显而易见,特别是对于较大规模的业务场景,可以节省下不少的机器资源与额外的维护成本。但是缺点也非常明显,一旦需要升级 Proxyless SDK 的能力,我们就需要升级SDK,需要修改代码、升级框架版本。 ## MSE 如何解决客户需要面对 Proxyless Mesh 的缺点 我们采取了一个策略,通过 JavaAgent 实现 xDS 协议。如此一来,Spring Cloud 就可以通过接入JavaAgent 来接入 Mesh 生态并且支持 istio 配置的路由规则,JavaAgent 通过 xDS 协议从 istiod 拉取其他服务的地址列表并转换成 Spring Cloud 负载均衡 Ribbon 的 ServerList 进行一次地址列表的集合合并操作。如此一来,原生 Spring Cloud 应用无需修改一行代码,就可以支持 Proxyless Mesh 模式,同时还兼容原先的 Nacos 体系的服务发现。 ![4.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/159fb803dcf24d51970488325c8babd4~tplv-k3u1fbpfcp-zoom-1.image "4.png") 另一方面,对于 Java 应用来说相比于 Envoy,JavaAgent 还可以提供更多的治理能力,比如,服务契约、接口信息、数据库流量的治理、JVM 监控与治理等等。 ## Spring Cloud 应用无侵入升级至 Proxyless Mesh 架构* * 下面我们通过一个简单的实践例子来体验 Spring Cloud 应用是如何无侵入升级至 Proxyless Mesh架构的。 **Demo:如何实现 Spring Cloud 应用与 Service Mesh 架构的多语言微服务的互通?** ![5.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/86633b1e14114c22a72b084f3d63fb71~tplv-k3u1fbpfcp-zoom-1.image "5.png") ### 前提条件 开启 MSE 服务治理能力,并且需要为当前 K8s 集群创建阿里云 ASM Istio 实例。 ### 第一步:部署Spring Cloud服务和多语言服务。 我们需要部署 Spring Cloud 应用与多语言 Go 应用 > Demo 应用的例子可以从以下文档中获取 **[3** **]** 其中 Spring Cloud 应用调用多语言服务的方式跟调用其他 Spring Cloud 应用之间互相调用的方式一致,例如,通过restTemplate工具请求调用Spring Cloud服务(应用名称为go-sc-a)的A接口如下: ``` restTemplate.getForObject("http://go-sc-a/A", String.class) ``` 您也可以使用其他方式调用,不需要对应服务的端口号,即可直接访问。 ### 第二步:通过配置环境变量方式开启 MSE Agent 支持 xDS 协议能力 我们需要增加如下环境变量,开启MSE Agent 的支持 xDS 协议的功能 ![6.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/44c36620edc2425a8ba51c463d91ff41~tplv-k3u1fbpfcp-zoom-1.image "6.png") ### 第三步:结果验证 Spring Cloud 服务与服务网格的多语言服务可以实现互通,且Spring Cloud服务调用多语言服务的方式不需要修改任何代码。 - Spring Cloud服务访问多语言服务: ``` ~ curl localhost:20003/go [Java Spring Cloud ] -> [Service Mesh APP10.191.XX.XX ] ``` - 多语言服务调用Spring Cloud服务 ``` ~ curl localhost:8085/java [ Service Mesh APP ] -> [Java Spring Cloud10.191.XX.XX] ``` ## 总结 本文通过一个 Demo 演示了 SpringCloud 应用通过接入MSE服务治理之后,无需修改任意代码就能具备 Proxyless Mesh的能力,当前 MSE 服务治理支持还有些限制,在持续补充完善中。当前 MSE 服务治理 Proxyless 模式支持基础的服务发现能力以及 DestinationRule 的 Subset 能力,我们可以配合 MSE 流量治理实现 Mesh 架构下的全链路灰度、标签路由等治理能力。 另外值得一提的是,我们正在与 CloudWeGo、Kratos、Spring Cloud Alibaba、Dubbo、ShardingSphere、Database Mesh 等社区共同建设 OpenSergo 微服务治理标准,我们希望可以将企业与社区中微服务治理的场景与最佳实践共同提取成标准规范。 我们欢迎更多社区与企业一起参与 OpenSergo 微服务治理标准的共建,OpenSergo 社区现在处于高速发展阶段,从微服务治理标准定义,到 Control Plane 的实现,再到 Java/Go/C++/Rust 等多语言 SDK 与治理功能的实现,再到各个微服务生态的整合与落地,都还有大量的演进工作,欢迎社区一起参与标准完善与代码贡献。 ![7.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87d93c8e3281446ca9380153f4991db2~tplv-k3u1fbpfcp-zoom-1.image "7.png") OpenSergo 开源贡献小组正在火热招募贡献者。如果您有时间,有热情,有意愿,欢迎联系社区加入开源贡献小组,一起共同完善 OpenSergo 和 Sentinel,一起主导微服务治理技术与标准演进。Now let's start hacking! 欢迎加入 OpenSergo 交流群:34826335 ***相关链接:*** [1] ** [2] ** [3] **