基于 Sermant 实现 xDS 服务网格,获取 15+ 倍更高性能和更低成本
Sermant 从 2.0.0 版本开始在框架层支持 xDS 协议,截止到目前最新发布的 2.1.0 版本, Sermant 在框架层已经实现了基于xDS协议的服务发现、路由配置和负载均衡配置信息的能力;并在路由插件对 HTTP 调用兼容了 xDS 协议。我们对 Sermant 和 Envoy 进行了性能对比,基于 Sermant 实现 xDS 服务网格只需增加 1.5%左右的计算资源,资源节省约 15 倍,并且性能收益显著提高。下文将详细介绍基于 Sermant 实现的 xDS 服务网格。
一、 服务网格
Istio 是目前应用最广泛的 Service Mesh 产品。如下图(图片摘自Istio官网)所示,由数据平面(Envoy 代理)和控制平面组成。
Istio 的数据平面一般会启动独立的 Sidecar 容器代理业务微服务的网络,因此会增加额外的性能损耗,包括 CPU 额外占用和调用时延的大幅增长,服务网格的问题分析可以参考云原生微服务治理技术朝无代理架构的演进之路一文。Sermant 在最近的版本中实现了基于 xDS 协议的服务治理能力,可以替代 Envoy 作为 Istio 的数据平面,从有代理服务网格跨进到了无代理服务网格,性能大幅提升。
二、Istio + Sermant 无代理服务网格
2.1 Sermant 无代理服务治理
Sermant 是一款开源的基于 Java 字节码增强技术的云原生无代理服务网格产品。Sermant 目前实现了基于通用数据平面通信协议(xDS 协议)和 Istio 控制平面通信的能力,并获取服务发现、路由、负载均衡配置等信息,从而可以作为 Istio 的数据平面完成服务治理能力。
Sermant 是基于 Java Agent 的云原生无代理服务网格,具有高性能、插件化和非侵入的优势。业务微服务挂载 Sermant 同进程运行,无需启动额外的 Sidecar 容器进行网络代理,可以大幅度降低应用的性能损耗和服务之间的调用时延。
Istio + Sermant 具有多种部署模式,包括混合部署和无代理部署模式:
• 混合部署模式:Sidecar 代理模式和 Sidecar 无代理模式共存。业务微服务通过混合部署模式接入 Istio 并实现服务治理能力,该模式可以避免修改已有的部署架构,仅新增服务使用 Sidecar 无代理模式,同时两种部署模式可以互相调用。
• 无代理部署模式:所有的业务微服务均使用 Sermant 作为 Istio 的数据平面实现服务发现、路由、负载均衡等能力。Sermant 可以替代 Envoy 提供的能力,当前已经支持了服务发现、路由和负载均衡,未来功能将持续演进。
除了部署模式的多样性,Istio 环境下使用 Sermant 还具有如下优势:
• Sermant 和业务微服务同进程运行,无需启动额外的 Sidecar 容器,大幅减少网络调用时延和 CPU 损耗。
• 基于 Sermant 框架开发插件可以实现比 Envoy 更丰富的治理能力,可扩展性更强。
• 更低的架构复杂度可以大幅降低部署成本。
2.2 Sermant 基于 xDS 协议的服务治理能力
Sermant 在框架层基于 xDS 协议实现了服务发现、路由配置和负载均衡配置的获取能力,并在路由插件支持了 xDS 协议,整体架构实现如如下图所示。本节将详细 Sermant 基于 xDS 协议的服务治理能力。
• 基于 xDS 协议的服务发现
Kubernetes 环境中,用户通过Deployment和Service自定义资源文件创建 Pod 和 Service。Sermant 基于 xDS 协议可以获取服务的所有运行实例。更多详细信息请参考 Sermant 官网基于xDS服务的服务发现一节。
• 基于 xDS 协议的路由
Istio 通过下发DestinationRule和VirtualService自定义资源文件下发路由配置。Sermant 通过和 Istio 的控制平面进行通信获取路由配置,并实现了基于 xDS 协议的路由能力。该能力具备通过 HTTP 请求的 Header 和 Path 进行路由的功能,并且支持同 AZ 路由。目前,它已支持 SpringCloud、HttpClient、HttpAsyncClient、OkHttp 以及 HttpURLConnection 等多个 HTTP 主流框架。更多详细信息请参考 Sermant 官网基于xDS服务的路由一节。
• 基于 xDS 协议的负载均衡
Istio 通过下发DestinationRule自定义资源文件下发负载均衡配置。Sermant 获取该配置并实现了基于 xDS 协议的负载均衡能力。目前在路由插件支持 Random 和 Round_Robin 负载均衡能力。更多详细信息请参考 Sermant 官网基于xDS服务的负载均衡一节。
三、Sermant 基于 xDS 协议的路由能力示例
用户存在如下场景和需求:spring-server 部署了 v1 和 v2 两个版本的实例,每个版本各有三个服务实例,运行在 node1 和 node2 两个节点;上游服务 spring-client 实例运行在 node1 节点,在调用 spring-server 时需要根据 http 请求的 header 选择路由的版本,对于满足路由规则的服务实例,优先选择同一 node 的实例,并使用轮训负载均衡策略选择最终实例。
用户使用 Sermant 基于 xDS 协议的路由能力即可实现上述需求,效果如下图所示。
通过 Deployment 和 Service 自定义资源文件启动 spring-client 和 spring-server 的服务实例并挂载 Sermant,同时启用 Sermant 路由插件的 xDS 路由能力,关于 xDS 路由能力的具体使用请参考 Sermant 官网基于xDS协议的路由文档。
服务启动后,为 Kubernetes 的 node 节点添加区域信息标签:
1. // 设置 node1 节点 region 标签为 node1
2. kubectl label nodes node1 topology.kubernetes.io/region=node1
3. // 设置 node2 节点 region 标签为 node2
4. kubectl label nodes node2 topology.kubernetes.io/region=node2
用户下发如下所示的 DestinationRule 和 VirtualService 自定义资源文件配置路由和负载均衡规则。
DestinationRule 配置文件:
1. apiVersion: networking.istio.io/v1alpha3
2. kind: DestinationRule
3. metadata:
4. name: spring-server-destinationrule
5. spec:
6. host: spring-server.default.svc.cluster.local
7. trafficPolicy:
8. loadBalancer:
9. simple: ROUND_ROBIN
10. subsets:
11. - name: v1
12. labels:
13. version: v1
14. trafficPolicy:
15. loadBalancer:
16. localityLbSetting:
17. enabled: true
18. subsets:
19. - name: v2
20. labels:
21. version: v2
22. trafficPolicy:
23. loadBalancer:
24. localityLbSetting:
25. enabled: true
VirtualService 配置文件:
1. apiVersion: networking.istio.io/v1alpha3
2. kind: VirtualService
3. metadata:
4. name: spring-server-virtualservice
5. spec:
6. hosts:
7. - spring-server
8. http:
9. - name: "v1-routes"
10. match:
11. - headers:
12. version:
13. exact: v1
14. uri:
15. prefix: /
16. ignoreUriCase: false
17. route:
18. - destination:
19. host: spring-server
20. subset: v1
21. port:
22. number: 8003
23. - name: "v2-route"
24. match:
25. - headers:
26. version:
27. exact: v2
28. uri:
29. prefix: /
30. ignoreUriCase: false
31. route:
32. - destination:
33. host: spring-server
34. subset: v2
35. port:
36. number: 8003
上述 DestinationRule 根据服务实例 Pod 的 version 标签,将服务实例划分为 v1 和 v2 两个子集,每个子集均使用同 AZ 路由策略和轮训负载均衡策略;VirtualService 指定 http 请求存在 version:v1 的 header,访问 v1 版本的服务实例的 8003 端口,存在 version:v2 的 header,访问 v2 版本服务实例的 8003 端口。
下发规则后,Sermant 在框架层基于 xDS 协议获取并解析该路由和负载均衡配置内容,路由插件拦截 http 调用过程实现基于 xDS 的路由能力,根据配置的路由规则选择最终的目标实例进行调用。
四、Sermant 性能表现
在 Istio 环境下,我们针对 Sermant(路由插件)和 Envoy 路由能力的性能进行了对比实验。性能测试场景为 spring-client 微服务查询 mysql 数据库获取数据,并调用下游 spring-server 微服务。使用 Sermant 官方仓库的xds-router-demo作为测试 Demo。
测试环境:Kubernetes 版本为 1.23.9;Istio 版本为 1.17.8;MySQL 版本为 8.0.40;Pod 容器环境规格为 4U8G。
具体使用的 http 框架包括 HttpClient、HttpAsyncClient、OkHttp 和 HttpURLConnection。路由规则为 http 请求存在 version:v1 的 header,路由至 v1 版本集群,并通过轮训负载均衡策略选择服务实例,如上图所示。
我们在固定的 2000tps 下压测五分钟,对比了 spring-client 微服务在基线场景(使用 Kubernetes 的 DNS 解析能力)、Sermant 路由场景和 Envoy 路由场景时的 CPU 占用率、平均调用时延指标。
如上图所示,相较于宿主微服务,使用 Sermant 导致增加的 CPU 占用率和调用时延较低,而 Envoy 的性能损耗则明显高于 Sermant。
Envoy 和 Sermant 相较于宿主微服务的具体性能测试数据如上表所示,对于不同 http 框架,使用 Envoy 路由相比于基线测试应用 CPU 占用率至少增加 17%以上,平均增加 21.4%,资源损耗较高;使用 Sermant 额外增加的 CPU 占用率不超过 1.5%,相较 Envoy 平均下降超 93%。
在调用时延方面,基线应用使用 Envoy 平均调用时延增加 1.1ms 以上,最多达 2ms;使用 Sermant 平均调用时延增加不超过 0.1ms,平均增加 0.07ms,相较于 Envoy 平均下降超 94%。
Istio + Sermant 的无代理服务网格架构有效解决了传统 Sidecar 代理的性能瓶颈,可以显著降低企业在 IaaS 层面的成本开销,比如原微服务架构,使用 Istio + Envoy 方案,可能增加 20+%的计算资源,而使用 Sermant 只需增加 1.5%左右的计算资源,资源节省约 15 倍,并且性能收益显著提高,Sermant 还能提供更丰富的服务治理能力,比如链路追踪、流量标签透传等。
五、总结和规划
Sermant 实现了基于 xDS 的服务发现、路由和负载均衡能力。Istio 环境下使用 Sermant 作为服务网格的数据平面,大幅减少了服务运行中的资源损耗和调用时延,相较 Envoy 性能更强悍。
作为 CNCF 基金会的官方项目,Sermant 将持续融入 Kubernetes 云生态:基于 xDS 协议支持更多的服务治理能力,比如流量控制等;同时适配 OpenTelemetry,采集指标、链路追踪等数据。
Sermant 作为专注于服务治理领域的字节码增强框架,致力于提供高性能、可扩展、易接入、功能丰富的服务治理体验,并会在每个版本中做好性能、功能、体验的看护,广泛欢迎大家的加入。
• Sermant 官网:https://sermant.io
• GitHub 仓库地址:https://github.com/sermant-io/Sermant
• 扫码加入 Sermant 社区交流群
评论