摘要:在分布式系统中,流量的防护与调度是确保系统稳定性的关键。随着微服务架构的普及,服务之间的调用关系变得复杂,任何流量的波动和异常都有可能导致服务失败、雪崩、资源耗尽等等问题。因此,对这些流量进行管理的重要性也愈发凸显,常见的流量调度手段包括:
尹航(露营) 阿里云基础设施
引言
在分布式系统中,流量的防护与调度是确保系统稳定性的关键。随着微服务架构的普及,服务之间的调用关系变得复杂,任何流量的波动和异常都有可能导致服务失败、雪崩、资源耗尽等等问题。因此,对这些流量进行管理的重要性也愈发凸显,常见的流量调度手段包括:
• 限流:通过限制请求的流速、拒绝多余的请求,防止流量超过系统承受能力上限。
• 并发度限制:对于依赖有限资源的服务(如线程池、数据库等),可通过并发度限制来保护重要的资源。
• 请求排队:当请求速率或请求并发度超过承受上限后,对超出限制的请求进行排队,以应对突发的流量洪峰,适用于流量突发场景。
• 请求优先级调度:当流量超过系统承受上限时,优先响应高优先级的请求,以保证重要业务的平稳运行(或对重要客户的高优先级响应)。
• 分用户限流:在多用户/租户场景下,对每个单独的用户/租户进行流速或并发度限制,以保证多个用户/租户之间的公平使用场景。
• 熔断场景:在调用链路中某个方法出现不稳定时(例如某方法出现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-2. 使用以下命令创建sleep.yaml。
kubectl apply -f-3. 执行以下命令,进入sleep应用Pod并向httpbin服务发起请求。
kubectl exec -it deploy/sleep -- url -I http://httpbin:8000/headers预期输出:
HTTP/1.1 200 OKserver: envoydate: Tue, 26 Dec 2023 07:23:49 GMTcontent-type: application/jsoncontent-length: 353access-control-allow-origin: *access-control-allow-credentials: truex-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的生成速率,同时又能应对一定程度的突发流量。
2. 执行以下命令创建RateLimtingPolicy。
kubectl apply -f-部分字段说明如下。关于字段的更多信息,请参见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 -- sh2. 执行以下命令,使用user1身份连续访问httpbin服务的/headers路径两次。
curl -H "user_id: user1" httpbin:8000/headers -vcurl -H "user_id: user1" httpbin:8000/headers -v预期输出:
3. 在第2步执行后的30秒内,执行以下命令,使用user2身份访问httpbin服务的/headers路径一次。
curl -H "user_id: user2" httpbin:8000/headers -v预期输出:
可以看到user2访问相同的路径并未触发限流,证明分用户限流成功。
流量调度策略的可观测性
除了流量调度策略的本身,对流量调度事件的观测和感知也是分布式系统高可用能力构建的重要组成部分。当限流、排队等事件发生时,需要有可观测与告警机制通知到用户,此时视情况可能需要进行服务扩容、或禁止特定用户的恶意行为等操作,以保障系统的后续稳定。
ASM流量调度套件的每个策略都支持相关监控指标的采集,并支持将采集的指标展示为Grafana大盘,帮助直观查看流量调度策略的执行情况。具体配置请参考使用RateLimitingPolicy实现分用户限流场景[4]。
总结
在服务网格体系下,社区服务网格Istio提供的限流、熔断等能力可能无法满足复杂微服务调用场景下丰富的流量调度需求。通过ASM流量调度套件,可以在维持服务网格对业务的无侵入特性下,扩展出多种丰富的流量调度能力,包括请求优先级调度、请求排队、并发度控制、分用户限流、渐进式上线等,让服务网格作为构建业务分布式系统高可用的基础设施。本文基于用户场景最为广泛的分用户限流场景进行了介绍,有关其它基于ASM流量调度套件的调度能力,请进一步参考使用ASM流量调度套件进行分布式系统流量控制[5]。
相关链接:
[1] 添加集群到ASM实例
[2] 通过控制面kubectl访问Istio资源
[3] RateLimitingPolicy CRD说明
[4] 使用RateLimitingPolicy实现分用户限流场景
[5] 使用ASM流量调度套件进行分布式系统流量控制
来源:小夏论科技