准备lua script
mkdir lua
创建lua/test.lua,并写入内容
local redis = require('resty.redis')
local red = redis.new()
red:set_timeout(1000)
local function close(red)
if not red then
return
end
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
end
end
local ok, err = red:connect("127.0.0.1",6379)
if not ok then
return close(red)
end
这边限制每秒2次(方便验证)
inc = red:incr("testlimit")
if inc >2 then
red:expire("testlimit",10)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
if inc <2 then
red:expire("testlimit",1)
end
close(red)
准备html/index.html,空文件即可
修改conf/nginx.conf
http {
server {
listen 8080;
location / {
default_type text/html;
access_by_lua_file "lua/test.lua";
}
}
}
重新加载配置
ps aux|grep nginx
想master进程发送信号
sudo kill -s SIGHUP pid
验证
连续执行3次
curl -v http://localhost:8080
可以看到403了
查看redis
redis-cli
ttl testlimit可以看到过期时间
总结
这里只是粗粒度的限流,如果要细粒度的限流,比如ip(可以判断X-Real-IP(),X-FORWARD-FOR(从 ngx.req.get_headers()中获取),以及ngx.var.remote_addr)