一些比较有用的库
awesome-resty
awesome-resty 这个项目,维护了几乎所有 OpenResty 可用的包。
lua-resty-jit-uuid
lua-resty-jit-uuid 用于生成 uuid,注意如果在容器中使用需要对种子特殊处理。
lua-rapidjson
lua-rapidjson,它是对 rapidjson 这个腾讯开源的 JSON 库的封装,以性能见长。支持 JSON Schema,JSON Schema 是一个通用的标准,借助这个标准,可以精确地描述接口中参数的格式,以及如何校验的问题。
1 | "stringArray": { |
lua-resty-worker-events
lua-resty-worker-events,可以实现 OpenResty 中 worker 间通信。
比如有一个场景,存在多个 worker,只有一个 worker 收到了更新操作,并把结果写入了共享字典和自己 worker 内的 lru 缓存。那么,其他的 worker 怎么才能被通知去更新这项配置?这个时候这个库就派上用场了。
lua-resty-limit-traffic
常用的流量控制算法,有漏桶和令牌桶。
lua-resty-limit-traffic,里面包含了 limit-req(限制请求速率)、 limit-count(限制请求数) 和 limit-conn (限制并发连接数)这三种不同的限制方式;并且提供了limit.traffic ,可以把这三种方式进行聚合使用。
Nginx 的限速模块
在 Nginx 中,limit_req 模块是最常用的限速模块,下面是一个简单的配置:
1 | limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; |
这段代码是把终端的 IP 地址作为 key,申请了一块名为 one 的 10M 的内存空间地址,并把速率限制为每秒 1 个请求。
在 server 的 location 中,还引用了 one 这个限速规则,并把 brust 设置为 5。
这就表示在超过速率 1r/s 的情况下,同时允许有 5 个请求排队等待被处理,给出了一定的缓存区。
要注意,如果没有设置 brust ,超过速率的请求是会被直接拒绝的。Nginx 的这个模块基于漏桶来实现,resty.limit.req ,本质都是一样的。
- 第一个问题是,限速的 key 被限制在 Nginx 的变量范围内,不能灵活地设置。比如,根据不同的省份和不同的客户端渠道,来设置不同的限速阈值,这种常见的需求用 Nginx 就没有办法实现。
- 另外一个更大的问题是,不能动态地调整速率,每次修改都需要重载 Nginx 服务。这样一来,根据不同的时间段限速这种需求,很难优雅的实现。
限速器的组合
1 | local lim1, err = limit_req.new("my_req_store", 300, 200) |
存在对 limiter 做演习的概念,第一个通过,被第二个拒绝,第一个不会被算做次数。
这样组合以后,就可以为多个限流器设置不同的阈值和 key,实现更复杂的业务需求。