【Nginx】nginx+lua+redis实现限流

概述

nginx、lua访问redis的三种方式

  1. HttpRedis模块
    指令少,功能单一,适合简单缓存。只支持get,select命令。
  2. HttpRedis2Module模块
    功能强大,比较灵活
  3. lua-resty-redis库
    OpenResty提供的API。适合复杂业务,节省内存。
    以上3个模块OpenResty都有集成

OpenResty : 基于nginx开源版本的一个扩展版本。集成了大量的精良的lua库。所以接下来我们就使用OpenResty来实现相应的功能

OpenResty的安装

shell 复制代码
# 安装wget 如果没有的话
yum install wget
# 下载资源库 这样yum就可以直接安装了
# 得到 openresty.repo
cd /etc/yum.repos.d/
wget https://openresty.org/package/centos/openresty.repo
# 安装openresty 安装目录:/usr/local/openresty
yum install openresty

编写nginx配置

shell 复制代码
cd /usr/local/openresty/nginx/conf
vim nginx-lua.conf

openresty 提供了几种方式来配置lua脚本需要先了解一下

  • content_by_lua 'ngx.say("hello my openrestry")' : 可以直接在配置文件中写入单行的lua脚本的字符串。
  • content_by_lua_block :可以在nginx配置文件中配置 多行的 lua脚本代码块
shell 复制代码
content_by_lua_block {
	ngx.say("hello");
	ngx.say("block");
}
  • content_by_lua_file /usr/local/openresty/nginx/lua/lua-test.lua: 可以配置lua脚本的文件路径
  • log_by_lua_file /usr/local/openresty/nginx/lua/lua-log-test.lua : 可以配置lua脚本的日志文件
shell 复制代码
# nginx-lua.conf
worker_processes 1;
error_log logs/error.log debug;
events {
	worker_connections 1024;
}

http {
	include mime.types;
	default_type application/octet-stream;
	sendfile on;
	# 连接的超时时间
	keepalive_timeout 65;
	server {
		listen 8080;
		location / {
			default_type text/html;
			# 此处可以写lua脚本的文件路径
			content_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_log.lua;
		}
	}
}
lua 复制代码
-- ip_limit_access.lua
ngx.say("ip limit lua");

先编写一个简单的脚本测试 看看是否配置成功。

重启nginx并加载指定配置

shell 复制代码
# 查看nginx是否启动
ps -ef | grep nginx
# 停止nginx
/usr/local/openresty/nginx/sbin/nginx -s stop
# 启动nginx  -p指定工作目录  -c 指定配置文件
/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/nginx/ -c /usr/local/openresty/nginx/conf/nginx-lua.conf
# 使用curl访问地址 测试成功
[root@localhost nginx]# curl http://localhost
ip limit lua

nginx_lua_redis限流

通过以上测试,nginx配置lua脚本已经通过接下来就可以开始实现限流功能了。

整体思路

编写nginx配置

编写配置ngin-ip-limit.conf

shell 复制代码
# ngin-ip-limit.conf
worker_processes 1;
error_log logs/error.log debug;
events {
	worker_connections 1024;
}
http {
	include mime.types;
	default_type application/octet-stream;
	server {
		listen 80;
		localtion / {
			default_type text/html;
			# 配置lua脚本文件路径
			access_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_access.lua;
			# 配置lua日志脚本路径
			log_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_log.lua;
			# 需要准备一个被代理的服务
			proxy_pass http://localhost:8080/;
		}
	}
}

编写lua日志脚本

lua 复制代码
-- ip_limit_log.lua
local ip = ngx.var.remote_addr;
ngx.log(ngx.INFO, "request ip is:"..ip);

编写lua限流脚本

需求:系统每秒限流2个请求,如果超过阈值(每秒2个请求),则系统限制10秒内,不能被访问

lua 复制代码
-- ip_limit_access.lua
ngx.log(ngx.INFO, "ip limit log");

local redis = require "resty.redis";
local red = redis:new();

-- 连接redis
red:connect("127.0.0.1",6379);

-- 判断是否限流
limit = red:get("limit");
if limit == '1' then
  return ngx.exit(503);
end
-- 次数加1
inc = red:incr("testLimit");
if inc <= 2 then
  -- 设置过期时间 1秒
  red:expire("testLimit",1);
else
  -- 超过阈值 limit设置成1 并设置过期时间10秒
  red:set("limit",1);
  red:expire("limit", 10);
end

测试

当快速方法时会报503错误。10秒后恢复正常访问。

相关推荐
程序员大辉1 小时前
接口调试利器,Postman免安装,免登陆
测试工具·lua·postman
DemonAvenger1 小时前
深入浅出 Redis 布隆过滤器:从原理到实战,10 年经验总结
数据库·redis·性能优化
天庭鸡腿哥2 小时前
可能最后一个版本,作者不更新了!
eclipse·maven·lua·visual studio
fruge10 小时前
Ubuntu服务器已下载Nginx安装包的安装指南
服务器·nginx·ubuntu
siriuuus11 小时前
Linux Tomcat 简单使用及 Nginx 反向代理
linux·nginx·tomcat
li37149089014 小时前
nginx报400bad request 请求头过大异常处理
java·运维·nginx
爬山算法14 小时前
Redis(66)Redis如何实现分布式锁?
数据库·redis·分布式
恋红尘15 小时前
Redis面试八股
数据库·redis·面试
Crazy________18 小时前
34部署LNMP架构详细解析
linux·运维·服务器·nginx
阿维的博客日记20 小时前
Redis学习笔记-QuickList
redis·笔记·学习