global-throttle: 通用流量控制,支持共享存储
安装
如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。
CentOS/RHEL 7 或 Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-global-throttle
CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-global-throttle
要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua。
本文档描述了 lua-resty-global-throttle v0.2.0,于 2020 年 12 月 30 日发布。
使用方法
这是一个通用的、分布式的流量控制实现,适用于 Openresty。它可以用于限制任何操作,无论是请求还是函数调用。目前仅实现了近似滑动窗口速率限制。
首先引入模块:
local global_throttle = require "resty.global_throttle"
之后,您可以像下面这样创建一个流量控制实例,其中 100 是每 2 秒窗口内强制执行的限制。第三个参数告诉流量控制器应该使用哪个存储提供者来存储其内部统计信息。
local memc_host = os.getenv("MEMCACHED_HOST")
local memc_port = os.getenv("MEMCACHED_PORT")
...
local my_throttle, err = global_throttle.new(namespace, 10, 2, {
provider = "memcached",
host = memc_host,
port = memc_port,
connect_timeout = 15,
max_idle_timeout = 10000,
pool_size = 100,
})
最后,您在每次要限制的操作之前调用以下内容:
local estimated_final_count, desired_delay, err = my_throttle:process("identifier of whatever it is your are throttling")
当 desired_delay 存在时,意味着限制已超出,客户端应该被限制 desired_delay 秒。
要更全面地了解如何使用此库,请参考 examples 目录。
生产注意事项
- 确保正确配置连接池大小。基本上,如果您的存储(即 memcached)可以处理
n个并发连接,而您的 NGINX 有m个工作进程,则连接池大小应配置为n/m。这是因为配置的池大小是每个 NGINX 工作进程的大小。例如,如果您的存储通常处理 1000 个并发请求,而您有 10 个 NGINX 工作进程,则连接池大小应为 100。同样,如果您有p个不同的 NGINX 实例,则连接池大小应为n/m/p。 - 在基于
desired_delay进行缓存决策时要小心,有时它太小,以至于您的缓存可以将其解释为 0,从而无限期缓存。此外,缓存很短的时间可能不会带来任何好处。
贡献与开发
该库设计为可扩展。目前仅在 lib/resty/global_throttle/sliding_window.lua 中实现了近似滑动窗口算法。它可以作为实现其他算法的参考点。
存储提供者在 lib/resty/global_throttle/store/ 中实现。
参考
- Cloudflare 关于近似滑动窗口的博客文章:https://blog.cloudflare.com/counting-things-a-lot-of-different-things/
GitHub
您可以在 nginx-module-global-throttle 的 GitHub 仓库 中找到此模块的其他配置提示和文档。