如何使用服务网格实现全方位的流量调度场景

简介: 阿里云服务网格(ASM)通过流量调度套件扩展了Istio的限流、熔断能力,实现分用户限流、请求排队等复杂流量管理功能,提升分布式系统高可用性与可观测性。

【阅读原文】戳:如何使用服务网格实现全方位的流量调度场景

 

引言

 

 

 

在分布式系统中,流量的防护与调度是确保系统稳定性的关键。随着微服务架构的普及,服务之间的调用关系变得复杂,任何流量的波动和异常都有可能导致服务失败、雪崩、资源耗尽等等问题。因此,对这些流量进行管理的重要性也愈发凸显,常见的流量调度手段包括:

 

限流:通过限制请求的流速、拒绝多余的请求,防止流量超过系统承受能力上限。

 

并发度限制:对于依赖有限资源的服务(如线程池、数据库等),可通过并发度限制来保护重要的资源。

 

请求排队:当请求速率或请求并发度超过承受上限后,对超出限制的请求进行排队,以应对突发的流量洪峰,适用于流量突发场景。

 

请求优先级调度:当流量超过系统承受上限时,优先响应高优先级的请求,以保证重要业务的平稳运行(或对重要客户的高优先级响应)。

 

分用户限流:在多用户/租户场景下,对每个单独的用户/租户进行流速或并发度限制,以保证多个用户/租户之间的公平使用场景。

 

熔断场景:在调用链路中某个方法出现不稳定时(例如某方法出现Timeout或异常比例升高),对这个方法的调用进行限制,让请求快速失败,避免此错误影响整个链路。

 

上述的流量防护手段通常通过中间件或框架来实现,而中间件或框架往往与业务逻辑紧密耦合。

 

服务网格作为云原生时代下新一代应用感知的云原生网络基础设施,通过在服务之间插入透明的网格代理,在对业务服务代码无侵入的情况下,实现了对服务间通信的统一管理、观测、安全等能力。

 

在服务网格Istio中,提供了基于EnvoyFilter方式使用的本地/全局限流能力、以及根据请求5xx响应数量对服务端点进行熔断的主机级别熔断能力。但对于上文中提到的请求排队/分用户限流/优先级调度/并发度限制等丰富的流量调度场景仍然无法满足。

 

 

 

 

使用服务网格实现丰富的流量调度场景

 

 

 

阿里云服务网格(Service Mesh,简称ASM)是一个全托管式的服务网格平台,兼容社区Istio开源服务网格,用于简化服务的治理,包括服务调用之间的流量路由与拆分管理、服务间通信的认证安全以及网格可观测性能力,从而极大地减轻开发与运维的工作负担。

 

ASM在服务网格架构的基础上,通过提供流量调度套件来满足用户丰富的流量防护与流量调度需求:ASM流量调度套件是基于服务网格的流量统一调度架构模式,以及基于该架构模式开发的多种流量调度策略的统称,旨在对云原生分布式应用中的请求进行统一的负载调度与管理。这些能力可以增强云原生分布式应用的可靠性,同时优化成本和资源利用效率。

 

ASM流量调度套件的核心架构主要包括ASM请求调度控制器和ASM请求调度Agent。当Sidecar转发Pod的出站或入站请求时,将与ASM请求调度Agent进行交互,并从Agent处获取流量调度决策,进而对请求进行限流、排队等调度行为。

 

 

ASM流量调度套件提供一系列预置的流量调度策略,这些策略将经过ASM请求调度控制器向ASM请求调度Agent进行发布,以动态控制流量负载的调度行为。

 

 

 

 

流量调度实践:基于ASM流量调度套件完成分用户限流场景

 

 

 

分用户/租户限流场景是在实际的用户需求中经常存在的场景:由于业务本身提供给大量的用户/租户,需要确保每个用户/租户的请求速率不超过给定阈值、并拒绝超出的请求,以保证租户之间的公平使用。典型的如代码仓库代管服务、平台服务等。

 

 

 

准备工作:环境部署

 

 

在实践中,我们通过部署httpbin和sleep示例服务来演示分用户限流场景。其中sleep服务扮演客户端、而httpbin服务扮演服务端。

 

1. 使用以下命令创建httpbin.yaml。

 

kubectl apply -f- <<EOF
##################################################################################################
# httpbin Service示例。
##################################################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs/httpbin:latest
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
EOF

 

2. 使用以下命令创建sleep.yaml。

 

kubectl apply -f- <<EOF
##################################################################################################
# Sleep Service示例。
##################################################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sleep
---
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
    service: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sleep
  template:
    metadata:
      labels:
        app: sleep
    spec:
      terminationGracePeriodSeconds: 0
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
        command: ["/bin/sleep", "infinity"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true
---
EOF

 

3. 执行以下命令,进入sleep应用Pod并向httpbin服务发起请求。

 

kubectl exec -it deploy/sleep -- url -I http://httpbin:8000/headers

 

预期输出:

 

HTTP/1.1 200 OK
server: envoy
date: Tue, 26 Dec 2023 07:23:49 GMT
content-type: application/json
content-length: 353
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 1

 

返回200 OK,表明访问成功。

 

 

 

步骤一:开启ASM流量调度套件

 

 

要使用ASM流量调度套件,首先需要确保ASM实例版本在1.21及以上,并且已经向ASM实例中添加Kubernetes集群。具体操作,请参见添加集群到ASM实例[1]

 

开启ASM流量调度套件的步骤如下:

 

1. 使用kubectl连接到ASM实例,具体操作,请参见通过控制面kubectl访问Istio资源[2]

 

2. 执行以下命令。

 

kubectl patch asmmeshconfig default --type=merge --patch='{"spec":{"adaptiveSchedulerConfiguration":{"enabled":true,"schedulerScopes":[{"namespace":"default"}]}}}'

 

 

 

步骤二:利用流量速率限制策略完成分用户限流

 

 

ASM流量调度套件包含多项高级的流量调度策略,其中流量速率限制策提供针对网格内指定服务服务提供全局限流能力,相比Istio社区限流方案增加分用户限流、设置突发流量窗口、自定义请求token消耗速率等高级限流功能。

 

限流策略采用令牌桶算法。系统以固定速率生成令牌(tokens),并加入到令牌桶中,直到容量上限。服务间的请求需要消耗tokens才能发送成功,如果桶中有足够的tokens,请求发送时将消耗token;如果没有足够的tokens,请求可能会被排队或丢弃。此算法可以保证数据传输的平均速率不会超过token的生成速率,同时又能应对一定程度的突发流量。

 

 

1. 使用kubectl连接到ASM实例,具体操作,请参见通过控制面kubectl访问Istio资源[2]

 

2. 执行以下命令创建RateLimtingPolicy。

 

kubectl apply -f- <<EOF
apiVersion: istio.alibabacloud.com/v1
kind: RateLimitingPolicy
metadata:
  name: ratelimit
  namespace: istio-system
spec:
  rate_limiter:
    bucket_capacity: 2
    fill_amount: 2
    parameters:
      interval: 30s
      limit_by_label_key: http.request.header.user_id
    selectors:
    - agent_group: default
      control_point: ingress
      service: httpbin.default.svc.cluster.local
EOF

 

部分字段说明如下。关于字段的更多信息,请参见RateLimitingPolicy CRD说明[3]

 

字段 说明
fill_amount 在interval指定的时间间隔内填充令牌的数量。示例中指定为2,即每过interval指定的时间间隔后便向令牌桶填充2个令牌。
interval 向令牌桶中填充令牌的时间间隔。示例中指定为30s,即每过30秒后便向令牌桶填充2个令牌。
bucket_capacity 令牌桶内的令牌数量上限。当请求速率小于令牌桶填充速率时,令牌桶内的令牌数量会持续增加,最大将达到bucket_capacity。使用bucket_capacity可以容许一定程度的突发流量。示例中设置为2,和fill_amount相同,即不允许任何突发流量。
limit_by_label_key 指定限流策略使用什么请求标签进行分组,指定后,不同标签的请求将分别进行限流,拥有相互独立的令牌桶。示例中使用http.request.header.user_id,其意义是使用请求的user_id请求头进行分组,模拟了分用户限流的场景。示例中假设不同的用户发起的请求拥有不同的used_id请求头。
selectors 指定应用限流策略的多个服务。示例中使用service: httpbin.default.svc.cluster.local表示对httpbin.default.svc.cluster.local服务进行限流。

 


 

步骤三:验证分用户限流效果

 

 

1. 执行以下命令,进入sleep应用开启bash。

 

kubectl exec -it deploy/sleep -- sh

 

2. 执行以下命令,使用user1身份连续访问httpbin服务的/headers路径两次。

 

curl -H "user_id: user1" httpbin:8000/headers -v
curl -H "user_id: user1" httpbin:8000/headers -v

 

预期输出:

 

< HTTP/1.1 429 Too Many Requests
< retry-after: 14
< date: Mon, 17 Jun 2024 11:48:53 GMT
< server: envoy
< content-length: 0
< x-envoy-upstream-service-time: 1
<
* Connection #0 to host httpbin left intact

 

3. 在第2步执行后的30秒内,执行以下命令,使用user2身份访问httpbin服务的/headers路径一次。

 

curl -H "user_id: user2" httpbin:8000/headers -v

 

预期输出:

 

< HTTP/1.1 200 OK
< server: envoy
< date: Mon, 17 Jun 2024 12:42:17 GMT
< content-type: application/json
< content-length: 378
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 5
<
{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin:8000",
    "User-Agent": "curl/8.1.2",
    "User-Id": "user2",
    "X-Envoy-Attempt-Count": "1",
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=ddab183a1502e5ededa933f83e90d3d5266e2ddf87555fb3da1ad40dde3c722e;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
  }
}
* Connection #0 to host httpbin left intact

 

可以看到user2访问相同的路径并未触发限流,证明分用户限流成功。

 

 

 

流量调度策略的可观测性

 

 

除了流量调度策略的本身,对流量调度事件的观测和感知也是分布式系统高可用能力构建的重要组成部分。当限流、排队等事件发生时,需要有可观测与告警机制通知到用户,此时视情况可能需要进行服务扩容、或禁止特定用户的恶意行为等操作,以保障系统的后续稳定。

 

ASM流量调度套件的每个策略都支持相关监控指标的采集,并支持将采集的指标展示为Grafana大盘,帮助直观查看流量调度策略的执行情况。具体配置请参考使用RateLimitingPolicy实现分用户限流场景[4]


 

 

 

 

 

总结

 

 

 

在服务网格体系下,社区服务网格Istio提供的限流、熔断等能力可能无法满足复杂微服务调用场景下丰富的流量调度需求。通过ASM流量调度套件,可以在维持服务网格对业务的无侵入特性下,扩展出多种丰富的流量调度能力,包括请求优先级调度、请求排队、并发度控制、分用户限流、渐进式上线等,让服务网格作为构建业务分布式系统高可用的基础设施。本文基于用户场景最为广泛的分用户限流场景进行了介绍,有关其它基于ASM流量调度套件的调度能力,请进一步参考使用ASM流量调度套件进行分布式系统流量控制[5]

 

 

相关链接:

 

[1] 添加集群到ASM实例

https://help.aliyun.com/zh/asm/user-guide/add-a-cluster-to-an-asm-instance

 

[2] 通过控制面kubectl访问Istio资源

https://help.aliyun.com/zh/asm/user-guide/use-kubectl-on-the-control-plane-to-access-istio-resources

 

[3] RateLimitingPolicy CRD说明

https://help.aliyun.com/zh/asm/user-guide/description-of-the-ratelimitingpolicy-crd

 

[4] 使用RateLimitingPolicy实现分用户限流场景

https://help.aliyun.com/zh/asm/user-guide/using-ratelimitingpolicy-to-implement-user-specific-flow-limiting/

 

[5] 使用ASM流量调度套件进行分布式系统流量控制

https://help.aliyun.com/zh/asm/user-guide/distributed-system-traffic-control-using-asm-traffic-scheduling-suite/



我们是阿里巴巴云计算和大数据技术幕后的核心技术输出者。

欢迎关注 “阿里云基础设施”同名微信微博知乎

获取关于我们的更多信息~

相关文章
|
3月前
|
Kubernetes 容灾 Cloud Native
服务网格容灾系列场景(三):使用服务网格应对服务级故障容灾
文章介绍了使用服务网格应对服务级故障容灾的实践:服务网格ASM通过多集群、多地域部署和基于地理位置的故障转移机制,实现服务级故障的自动检测与秒级流量切换,能够确保业务在复杂故障场景下的高可用性。
|
3月前
|
Kubernetes 容灾 网络协议
服务网格容灾系列场景(一):使用服务网格应对地域级故障容灾
介绍基于服务网格ASM、通过在多地域部署Kubernetes集群和ASM网关,结合云解析DNS和全局流量管理GTM,实现地域级故障的自动检测与流量转移,确保业务连续性和高可用性。
|
3月前
|
Prometheus 监控 负载均衡
服务网格容灾系列场景(二):使用服务网格应对可用区级故障容灾
文章介绍了如何使用阿里云服务网格ASM和容器服务Kubernetes版ACK应对可用区级故障容灾,通过多可用区部署、流量管理和可观测性保障业务连续性,确保在单个可用区故障时,其他可用区仍能正常提供服务。
|
监控 安全 大数据
阿里服务的ASM、MSE和ARMS都有其各自的应用场景
阿里服务的ASM、MSE和ARMS都有其各自的应用场景
576 39
|
弹性计算 运维 Serverless
使用ASM Serverless网关支撑各种弹性业务场景
ASM Serverless网关就是基于虚拟节点和ECI提供的一种Serverless 网关形态,充分支撑各种弹性和免节点运维场景的用户诉求。
249 1
ASM中GRPC/HTTP2流式传输场景的Sidecar资源占用调优
当应用使用GRPC流式传输时,数据经由Sidecar进行转发,由于Sidecar工作于7层,所以Sidecar会对GRPC消息元信息进行解析后在转发,在一些场景下(例如在单连接上建立大规模Stream)可能会造成Sidecar内存占用提升。本文将介绍Sidecar控制GRPC流式传输性能的相关参数和其作用机制,用户可以通过这些参数对Sidecar资源占用进行调整,已取得运行性能和资源消耗的平衡。S
257 0
ASM中GRPC/HTTP2流式传输场景的Sidecar资源占用调优
|
Prometheus 监控 Kubernetes
使用ASM网格拓扑观测多集群的流量控制与容灾场景
作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月
|
运维 Kubernetes 安全
解锁ASM网关:一致的规则配置, 多样化的入出口网关场景
作为业内首个全托管Istio兼容的服务网格产品ASM,一开始从架构上就保持了业界领先性、以及与社区发展的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立, 保持高可用部署与稳定性。阿里云ASM产品是基于社区开源的Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵
303 0
解锁ASM网关:一致的规则配置, 多样化的入出口网关场景
|
机器学习/深度学习 人工智能 Kubernetes
服务网格驱动的新场景定义:AI 模型服务 Model Mesh
这个能力来源于我们的实际客户的诉求。 这些客户使用场景就是希望在服务网格技术之上运行KServe来实现AI服务。KServe平滑运行于服务网格之上, 实现模型服务的蓝/绿和金丝雀部署、修订版本之间的流量分配等能力。支持自动伸缩的Serverless推理工作负载部署、支持高可扩展性、基于并发的智能负载路由等能力。
1243 0
服务网格驱动的新场景定义:AI 模型服务 Model Mesh
下一篇
oss创建bucket