0%

《OpenResty精华整理》7.一些比较有用的库

一些比较有用的库

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
2
3
4
5
6
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}

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
2
3
4
5
6
7
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
location /search/ {
limit_req zone=one burst=5;
}
}

这段代码是把终端的 IP 地址作为 key,申请了一块名为 one 的 10M 的内存空间地址,并把速率限制为每秒 1 个请求。

在 server 的 location 中,还引用了 one 这个限速规则,并把 brust 设置为 5。

这就表示在超过速率 1r/s 的情况下,同时允许有 5 个请求排队等待被处理,给出了一定的缓存区。

要注意,如果没有设置 brust ,超过速率的请求是会被直接拒绝的。Nginx 的这个模块基于漏桶来实现,resty.limit.req ,本质都是一样的。

  • 第一个问题是,限速的 key 被限制在 Nginx 的变量范围内,不能灵活地设置。比如,根据不同的省份和不同的客户端渠道,来设置不同的限速阈值,这种常见的需求用 Nginx 就没有办法实现。
  • 另外一个更大的问题是,不能动态地调整速率,每次修改都需要重载 Nginx 服务。这样一来,根据不同的时间段限速这种需求,很难优雅的实现。

限速器的组合

1
2
3
4
5
6
7
8
9
10
local lim1, err = limit_req.new("my_req_store", 300, 200)
local lim2, err = limit_req.new("my_req_store", 200, 100)
local lim3, err = limit_conn.new("my_conn_store", 1000, 1000, 0.5)

local limiters = {lim1, lim2, lim3}
local host = ngx.var.host
local client = ngx.var.binary_remote_addr
local keys = {host, client, client}

local delay, err = limit_traffic.combine(limiters, keys, states)

存在对 limiter 做演习的概念,第一个通过,被第二个拒绝,第一个不会被算做次数。
这样组合以后,就可以为多个限流器设置不同的阈值和 key,实现更复杂的业务需求。