跳到正文
Træfɪk

<span class="nav-link-with-icon">Distributed RateLimit <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>

Traefik Hub 功能

此中间件仅在 Traefik Hub 中提供。了解更多 Traefik Hub 高级功能。

Distributed RateLimit 中间件确保在整个集群范围内按时间限制请求数量,而不仅限于单个代理。

它基于令牌桶实现。


配置示例

以下高级配置启用了以 Redis 为后端的 Distributed RateLimit 中间件,从而实现集群范围的限流。

# Here, a limit of 100 requests per second is allowed.
# In addition, a burst of 200 requests is allowed.
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-distributedratelimit
  namespace: traefik
spec:
  plugin:
    distributedRateLimit:
      burst: 200
      limit: 100
      period: 1s
      denyOnError: false
      responseHeaders: true
      sourceCriterion:
        ipStrategy:
          excludedIPs:
            - 172.20.176.201
      store:
        redis:
          endpoints:
            - my-release-redis-master.default.svc.cluster.local:6379
          # Use the field password of the Secret redis in the same namespace
          password: urn:k8s:secret:redis:password
          timeout: 500ms
apiVersion: v1
kind: Secret
metadata:
  name: redis
  namespace: traefik
stringData:
  password: mysecret12345678

速率与突发容量

速率由 limit 除以 period 定义。 要实现低于每秒 1 个请求的速率,请将 period 设为大于 1 秒的值。

此中间件基于令牌桶实现。 在这个类比中,limit 和 period 参数定义令牌桶补充令牌的速率,burst 则是令牌桶的大小(容量)。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-ratelimit
spec:
  plugin:
    distributedRateLimit:
      burst: 100
      period: 1m
      limit: 6

在上述示例中,中间件最多允许 100 个并行连接(burst)。 每个连接消耗一个令牌。100 个令牌全部消耗后,其他连接会被阻止,直到桶中至少有一个可用令牌。

当桶未满时,每 10 秒生成一个令牌,即每 1 分钟生成 6 个(period / limit)。

配置选项

字段 说明 默认值 必填
limit 配合 period 定义速率的请求数。
0 表示不限流。
更多信息见此处。
0 否
period 用于定义速率的时间周期。
更多信息见此处。
1s 否
burst 同一时刻允许通过的最大请求数。
更多信息见此处。
1 否
denyOnError 限流存储(Redis)不可用时是否拒绝请求。设为 false 时,若无法连接 Redis,则允许请求通过。 true 否
responseHeaders 是否向响应中注入限流头(X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset)。 false 否
store.redis.endpoints 要连接的 Redis 实例端点(例如 redis.traefik-hub.svc.cluster.local:6379)。 "" 是
store.redis.username Traefik Hub 连接 Redis 时使用的用户名。 "" 否
store.redis.password Traefik Hub 连接 Redis 时使用的 password。 "" 否
store.redis.database Traefik Hub 用于存储信息的数据库。Redis Cluster 模式下不可用(仅支持数据库 0)。 0 否
store.redis.timeout Redis 连接的拨号、读取和写入操作所使用的超时时间。 "" 否
store.redis.cluster 启用 Redis Cluster 模式。设置为 {} 时启用;省略时禁用。不能与 store.redis.sentinel 同时使用。 - 否
store.redis.sentinel.masterSet Redis Sentinel 主节点集合名称。不能与 store.redis.cluster 同时使用。 "" 是(使用 Sentinel 时)
store.redis.sentinel.username 向 Redis Sentinel 认证时使用的用户名。 "" 否
store.redis.sentinel.password 向 Redis Sentinel 认证时使用的密码。 "" 否
store.redis.tls.ca 自定义 CA 证书包。 "" 否
store.redis.tls.cert TLS 证书。 "" 否
store.redis.tls.key TLS 密钥。 "" 否
store.redis.tls.insecureSkipVerify 允许跳过 TLS 验证。 false 否
sourceCriterion.requestHost 是否将请求主机作为来源。
sourceCriterion 的更多信息见此处。
false 否
sourceCriterion.requestHeaderName 用于对传入请求进行分组的请求头名称。
sourceCriterion 的更多信息见此处。
"" 否
sourceCriterion.ipStrategy.depth 从右侧开始,在 X-Forwarded-For 头中选择 IP 的深度位置。
0 表示不使用深度。
如果大于 X-Forwarded-For 中的 IP 总数,客户端 IP 为空。
如果大于 0,则不计算 excludedIPs 选项。
更多信息参阅下文的 sourceCriterion、ipStrategy 和 depth。
0 否
sourceCriterion.ipStrategy.excludedIPs 允许 Traefik 扫描 X-Forwarded-For 头,选取第一个不在此列表中的 IP。
如果指定了 depth,则忽略 excludedIPs。
更多信息参阅下文的 sourceCriterion、ipStrategy 和 excludedIPs。
否

sourceCriterion 来源判定标准

sourceCriterion 选项定义将请求归为同一来源时使用的判定标准。 如果同时定义多种策略,将报错。 如果均未设置,默认使用请求的远程地址字段(作为 ipStrategy)。

ipStrategy IP 策略

ipStrategy 选项定义 depth 和 excludedIPs 两个参数,用于配置 Traefik 如何确定客户端 IP。

限流作为中间件,在实际向后端代理请求之前执行。 此外,前一网络跳点仅在代理过程的最后阶段才会追加到 X-Forwarded-For 中,此时请求已经过限流。 因此,在限流期间,前一网络跳点尚未出现在 X-Forwarded-For 中,无法找到它,也不能依赖它。

sourceCriterion.ipStrategy.depth 深度

如果 depth 设置为 2,且请求的 X-Forwarded-For 头为 "10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1",则“真实”客户端 IP 为 "10.0.0.1"(深度为 4),但用作判定标准的 IP 是 "12.0.0.1"(depth=2)。

X-Forwarded-For depth clientIP(客户端 IP)
"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1" 1 "13.0.0.1"
"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1" 3 "11.0.0.1"
"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1" 5 ""

sourceCriterion.ipStrategy.excludedIPs 排除的 IP

尽管名称可能引起误解,此选项并不是将某个 IP 排除在限流器之外,因此不能用来停用某些 IP 的限流。

excludedIPs 用于解决两类略有不同的使用场景:

  1. 区分位于同一组反向代理后面的 IP,使它们各自独立计入自己的限流“桶”(参见令牌桶)。 在这种情况下,应将 excludedIPs 设置为要排除的 X-Forwarded-For IPs 列表,从而找到真正的客户端 IP。

将每个 IP 用作独立来源的示例:

X-Forwarded-For excludedIPs clientIP(客户端 IP)
"10.0.0.1,11.0.0.1,12.0.0.1" "11.0.0.1,12.0.0.1" "10.0.0.1"
"10.0.0.2,11.0.0.1,12.0.0.1" "11.0.0.1,12.0.0.1" "10.0.0.2"
  1. 将一组 IP(同样位于共同的一组反向代理之后)归为一组,使其被视为同一来源,并全部计入同一个限流桶。

将多个 IP 归为同一来源的示例:

X-Forwarded-For excludedIPs clientIP(客户端 IP)
"10.0.0.1,11.0.0.1,12.0.0.1" "12.0.0.1" "11.0.0.1"
"10.0.0.2,11.0.0.1,12.0.0.1" "12.0.0.1" "11.0.0.1"
"10.0.0.3,11.0.0.1,12.0.0.1" "12.0.0.1" "11.0.0.1"

store 存储

Distributed Rate Limit 中间件使用持久化 KV 存储保存数据。

参阅 Redis 选项来配置 Redis 连接。

Redis 服务器的连接参数配置在 Middleware 部署中。

支持以下 Redis 模式:

更多 Redis 信息,建议参阅 Redis 官方文档。

提示

如果使用 Redis 单实例模式或 Redis Sentinel,可以配置 database 字段。 如果使用 Redis Cluster,此值不会生效(仅可使用数据库 0)。

此时将显示一条警告,并忽略该值。


版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证