ASM在1.21版本提供了Peak EWMA(Exponentially Weighted Moving Average)负载均衡器,该负载均衡器通过计算静态权重、延迟、错误率等的移动平均值得出节点的分值进行负载均衡选择。当后端服务需要处理突然增加的流量时,ASM可以通过Peak EWMA算法关注实例的最高负载和实时响应时间,灵活地对流量进行分配,从而更好地处理流量峰值。本文介绍如何配置和使用指数加权移动平均(EWMA)实现基于工作负载延迟的负载均衡。
背景信息
服务网格ASM提供了多种常见的负载均衡算法,包括轮询、最少请求数、随机等。这些算法可以满足大多数业务场景的需求,并保证一定的性能表现。但是这些算法只能根据静态规则来进行后端选择,不会考虑后端实例的实时状态和性能。
例如,某网格使用默认的负载均衡算法,其后端服务的一个Pod由于所在的宿主机资源被其他应用占用而响应迟缓,导致请求延时增加甚至超时,而其他几个Pod则相对空闲。在这种情况下,如果负载均衡器能智能地避开这个性能异常的Pod,将流量更多地路由至其他相对空闲的Pod,这样可以显著地降低应用整体的错误率和响应延迟。
前提条件
已创建实例版本在1.21及以上的ASM实例。具体操作,请参见创建ASM实例。
已添加ACK集群到ASM实例。具体操作,请参见添加集群到ASM实例和升级ASM实例。
已通过kubectl工具连接集群。具体操作,请参见通过kubectl工具连接集群。
使用方法
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击使用YAML创建。
填入以下示例内容,单击创建。此示例YAML为命名空间default下的服务simple-server指定了
PEAK_EWMA
负载均衡算法。apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: simple-server namespace: default spec: host: simple-server.default.svc.cluster.local trafficPolicy: loadBalancer: simple: PEAK_EWMA # 指定使用ASM PEAK_EWMA负载均衡器
使用示例
示例介绍
本示例使用simple-server应用作为服务端,sleep应用作为发起测试流量的客户端,基于simple-server应用的服务simple-server.default.svc.cluster.local服务作为服务端。该服务下包含两个不同配置的deployment:
simple-server-normal:该Deployment配置返回延迟范围50~100ms。
simple-server-hight-latency:该Deployment配置返回延迟范围为500~2000ms,使用该deployment来模拟一个服务下部分工作负载延迟增高的情况。
步骤一:为ASM实例启用监控指标
为了更加直观地体现Peak EWMA负载均衡器的效果,本示例通过启用ASM监控指标来观察启用Peak EWMA负载均衡前后服务整体响应时间变化。关于启用监控指标以及采集监控指标到ARMS,请参见将监控指标采集到可观测监控Prometheus版。
步骤二:环境部署
在ACK集群对应的KubeConfig环境下,使用以下YAML创建sleep.yaml。
执行以下命令,部署sleep应用。
kubectl apply -f sleep.yaml
使用以下内容创建simple.yaml。
执行以下命令部署simple-server-normal和simple-server-high-latency应用。
kubectl apply -f simple.yaml
步骤三:以默认负载均衡算法发起测试
本节是基于默认负载均衡算法LEAST_REQUEST
产生基准数据。
执行以下命令发起测试,该命令会向simple-server服务发起100次
/hello
调用:kubectl exec -it deploy/sleep -c sleep -- sh -c 'for i in $(seq 1 100); do time curl simple-server:8080/hello; echo "request $i done"; done'
预期输出如下:
hello this is port: 8080real 0m 0.06s user 0m 0.00s sys 0m 0.00s request 1 done hello this is port: 8080real 0m 0.09s user 0m 0.00s sys 0m 0.00s request 2 done ...... hello this is port: 8080real 0m 1.72s user 0m 0.00s sys 0m 0.00s request 100 done
命令执行完毕后,在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择
,选择网格服务级别监控选项卡,输入以下筛选条件:Namespace:
default
Service:
simple-server.default.svc.cluster.local
Reporter:
destination
Client Workload
Namespace: default
Client Workload:
sleep
Service Workload Namespace:
default
Service Workload:
simple-server-normal + simple-server-high-latency
单击Client Workloads下拉菜单,查看Incoming Request Duration By Source面板。
可以看到,sleep应用到
simple-server
服务的请求响应时间P50为87.5ms,P95则上升较为显著,达到了2.05s,这是因为simple-server-high-latency
的延迟较高,增加了整个服务的响应时间。重要上述步骤中提到的测试结果是在受控实验环境下得出的理论数值,实际结果可能会因您的业务环境不同而有所差异。
步骤四:配置Peak EWMA负载均衡算法再次测试
创建DestinationRule为simple-server服务应用配置Peak EWMA负载均衡算法。
参考使用方法中的步骤和以下YAML内容创建目标规则。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: simple-server namespace: default spec: host: simple-server.default.svc.cluster.local trafficPolicy: loadBalancer: simple: PEAK_EWMA
在ACK集群对应的KubeConfig环境下,执行以下命令再次发起测试。
kubectl exec -it deploy/sleep -c sleep -- sh -c 'for i in $(seq 1 100); do time curl simple-server:8080/hello; echo "request $i done"; done'
对照步骤三中查看监控指标的步骤及结果,可以看到P90、P95、P99响应时间明显下降。这是因为Peak EWMA负载均衡器发现了simple-server-high-latency工作负载的延迟较高,降低了它的负载均衡权重,从而将更多的请求分配至延迟更低的simple-server-normal,从服务整体的视角观察,请求的整体延迟显著降低了。