彩票类网站开发,“一个”网站,外贸订单怎样去寻找,北京ifc大厦需求#xff1a;在Nginx上实现一个动态拦截IP的方法#xff0c;具体是当某个IP在1分钟内访问超过60次时#xff0c;将其加入Redis并拦截#xff0c;拦截时间默认1天。
技术选型#xff1a;使用NginxLuaRedis的方法。这种方案通过Lua脚本在Nginx处理请求时检查Redis中的黑…需求在Nginx上实现一个动态拦截IP的方法具体是当某个IP在1分钟内访问超过60次时将其加入Redis并拦截拦截时间默认1天。
技术选型使用NginxLuaRedis的方法。这种方案通过Lua脚本在Nginx处理请求时检查Redis中的黑名单同时统计访问频率超过阈值就封禁。这应该符合用户的需求。
需要结合Lua脚本和Redis的计数功能。安装OpenResty配置Nginx的Lua模块编写Lua脚本统计访问次数使用Redis存储和过期键以及设置拦截逻辑。连接池的使用避免频繁连接Redis影响性能。
一、环境准备 安装OpenResty OpenResty集成了Nginx和Lua模块支持直接运行Lua脚本 # Ubuntu/Debian
sudo apt-get install openresty
# CentOS
yum install openresty 安装Redis服务 sudo apt-get install redis-server # Debian系
sudo yum install redis # RedHat系 二、Nginx配置
主配置文件nginx.conf 在http块中添加共享内存和Lua脚本路径 http {lua_package_path /usr/local/openresty/lualib/?.lua;;;lua_shared_dict ip_limit 10m; # 共享内存区server {listen 80;server_name _;location / {access_by_lua_file /usr/local/lua/ip_block.lua; # 核心拦截脚本root /var/www/html;}}
} 三、Lua脚本实现动态拦截 脚本路径 创建Lua脚本/usr/local/lua/ip_block.lua 脚本内容 local redis require resty.redis
local red redis:new()-- Redis连接参数
local redis_host 127.0.0.1
local redis_port 6379
local redis_timeout 1000 -- 毫秒
local redis_auth nil -- 无密码留空-- 拦截参数
local block_time 86400 -- 封禁时间1天
local time_window 60 -- 统计窗口1分钟
local max_requests 60 -- 最大请求数-- 获取客户端IP
local function get_client_ip()local headers ngx.req.get_headers()return headers[X-Real-IP] or headers[x_forwarded_for] or ngx.var.remote_addr
end-- 连接Redis
local function connect_redis()red:set_timeout(redis_timeout)local ok, err red:connect(redis_host, redis_port)if not ok thenngx.log(ngx.ERR, Redis连接失败: , err)return nilendif redis_auth thenlocal ok, err red:auth(redis_auth)if not ok then ngx.log(ngx.ERR, Redis认证失败: , err) endendreturn ok
end-- 主逻辑
local client_ip get_client_ip()
local counter_key limit:count: .. client_ip
local block_key limit:block: .. client_ip-- 检查是否已封禁
local is_blocked, err red:get(block_key)
if tonumber(is_blocked) 1 thenngx.exit(ngx.HTTP_FORBIDDEN) -- 直接返回403
end-- 统计请求次数
connect_redis()
local current_count red:incr(counter_key)
if current_count 1 thenred:expire(counter_key, time_window) -- 首次设置过期时间
end-- 触发封禁条件
if current_count max_requests thenred:setex(block_key, block_time, 1) -- 封禁并设置1天过期red:del(counter_key) -- 删除计数器ngx.exit(ngx.HTTP_FORBIDDEN)
end-- 释放Redis连接
red:set_keepalive(10000, 100) 四、性能优化 Redis连接池 通过set_keepalive复用连接避免频繁建立TCP连接 共享内存缓存 使用lua_shared_dict缓存高频访问IP减少Redis查询压力 异步日志记录 封禁操作异步写入日志文件避免阻塞请求处理 ngx.timer.at(0, function()local log_msg string.format(%s - IP %s blocked at %s, ngx.var.host, client_ip, ngx.localtime())local log_file io.open(/var/log/nginx/blocked_ips.log, a)log_file:write(log_msg, \n)log_file:close()
end) 五、验证与测试 手动触发封禁 # 模拟高频请求
ab -n 100 -c 10 http://your-domain.com/
# 检查Redis
redis-cli keys limit:block:* 自动解封验证 等待24小时后检查封禁IP是否自动删除 redis-cli ttl limit:block:1.2.3.4 # 返回剩余秒数 六、扩展方案 分布式封禁 在多台Nginx服务器间共享Redis黑名单实现集群级拦截 可视化监控 通过GrafanaPrometheus展示实时拦截数据 # 采集Redis指标
prometheus-redis-exporter --redis.addresslocalhost:6379 动态调整阈值 通过Redis Hash存储不同路径的拦截规则 local rule_key limit:rule: .. ngx.var.uri
local custom_rule red:hget(rule_key, max_requests) 引用说明
核心拦截逻辑参考了NginxLuaRedis的经典架构设计
Redis键过期机制确保自动解封性能优化方案借鉴了OpenResty最佳实践