在面临高流量冲击、服务过载、资源耗尽或恶意攻击的情况下,通过配置限流防护,可以实现对流量的精准控制,从而保护后端服务的稳定性,降低成本并提升用户体验。本文介绍限流防护的概念、限流方式以及本地限流和全局限流的实现原理。
限流防护的概念
限流防护是一种限制发送到服务端的请求数量的机制。它指定客户端在给定时间段内可以向服务端发送的最大请求数,通常表示为一段时间内的请求数,例如每分钟300个请求或每秒10个请求等。限流的目的是防止服务因来自同一客户端IP或来自任何客户端的全局请求而过载。
以每分钟300个请求的限流机制为例,向服务发送301个请求,限流器将拒绝第301个请求。同时,限流器会返回一个429 HTTP状态码(Too Many Requests),并在请求到达服务之前进行拒绝。
限流防护的方式
网格代理Envoy支持两种类型的限流防护方式:本地限流和全局限流。本地限流用于限制每个服务实例的请求速率。全局限流使用全局的gRPC服务为整个网格提供限流能力。本地限流可以与全局限流结合使用,以提供不同层面的限流功能。
方式 | 说明 | 相关文档 |
本地限流 |
| |
全局(或分布式)限流 |
|
本地限流的工作原理
Envoy代理使用令牌桶算法实现本地限流。令牌桶算法是一种限制发送到服务端的请求数量的方法,基于一定数量的令牌桶。存储桶以恒定的速率不断填充令牌,当向服务发送请求时,会从存储桶中删除一个令牌。如果存储桶为空,则请求将被拒绝。通常需要指定以下内容:
桶被填充的速率(填充间隔)。
每个填充间隔添加到桶中的令牌数。
默认情况下,当速率限制器拒绝请求,并设置x-envoy-ratelimited响应标头时,Envoy会发送状态码为429的HTTP响应。您也可以将速率限制器配置为返回自定义HTTP状态代码,并配置其他响应标头。
此外,使用速率限制器有以下两个重要概念:
启用速率限制器:表示正在对速率限制器进行配置,但速率限制器并未应用于请求。
执行速率限制器:表示对请求应用或执行速率限制器。
将这两个值表示为传入请求的百分比,例如可以设置为10%的请求启用速率限制器,并为5%的请求强制执行。按照这种方式,可以逐步推出限流,并在对所有请求强制执行之前对其进行测试。
全局限流的工作原理
在Envoy代理中,全局限流是一种用于控制整个服务网格中请求速率的机制。它基于Envoy的限流服务(Rate Limit Service)实现。该服务可以集中处理来自整个服务网格中的流量,并根据预先定义的规则和配额来限制请求的速率。
全局限流的配置涉及两个部分:Envoy的rate_limits过滤器和限流服务的配置。
rate_limits过滤器中包含
actions
列表。Envoy会尝试将每个请求与rate_limits过滤器中的每个action进行匹配。每个action会生成一个descriptor描述符。描述符是与action对应的一组描述符条目。每个描述符条目是一个键值对,通常表示为"descriptor-key-1": "descriptor-value-1"
、"descriptor-key-2": "descriptor-value-2"
等形式。更多信息,请参见config-http-filters-rate-limit。限流服务的配置则能够匹配每个请求所产生的描述符条目。针对特定的一组描述符条目,限流服务的配置能够指定其对应的请求速率限制。限流服务通过与Redis缓存交互来决定是否对请求进行限流,并将限流决策响应给Envoy代理。
通过结合rate_limits过滤器和限流服务的配置,可以实现全局限流策略。rate_limits过滤器根据配置的action生成描述符,并将其发送到限流服务。限流服务根据描述符的信息来决定特定的限制,并返回相应的限流响应。这样的配置能够全面控制请求的速率,保护后端服务免受突发高负载请求的影响。