头图

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环境中,用户通过DeploymentService 自定义资源文件创建Pod和Service。Sermant基于xDS协议可以获取服务的所有运行实例。更多详细信息请参考Sermant官网基于xDS服务的服务发现 一节。

基于xDS协议的路由

Istio通过下发DestinationRuleVirtualService 自定义资源文件下发路由配置。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。

image.png

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 社区交流群


华为云开源
6 声望3 粉丝