​ 在我们生产环境中使用到了地图服务,每个月有免费请求次数,近一个月请求次数突然暴涨,导致直接开启付费模式,一个月上百刀的花销着实难扛,根据实际我们的业务使用情况,远达不到付费标准,故考虑做白名单和限流措施,基于以上情况并遇到春节急需快速处理,所以选择了最简单方便的方式,通过nginx做限流

​ 我们都知道nginx里面是可以用lua脚本做一些稍微复杂些的逻辑处理的,要使用lua脚本需要编译lua解释器,时间有限我直接用了openresty,它集成了lua和nginx

1、openresty是什么?

OpenResty是一个基于Nginx的高性能Web平台,用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。具备下列特点:

具备Nginx的完整功能

基于Lua语言进行扩展,集成了大量精良的 Lua 库、第三方模块,允许使用Lua自定义业务逻辑、自定义库

二、OpenResty的安装

1、添加OpenResty仓库

# 由于公共库中找不到openresty,所以需要添加openresty的源仓库
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo # 注意,如果上面命令提示不存在,那就先安装一下
yum install -y yum-utils

2. 安装OpenResty

# 安装openresty
yum install -y openresty
# 安装OpenResty管理工具,帮助我们安装第三方的Lua模块
yum install -y openresty-opm

3、目录结构

​ 默认安装在/usr/local/openresty

![image-20240205182218056](/Users/sunarmy/Library/Application Support/typora-user-images/image-20240205182218056.png)

看到里面有一个nginx目录,进去可以看到跟我们平常用的nginx是一模一样的,OpenResty就是在Nginx基础上集成了一些Lua模块

到这里我们就安装好了

7. 启动和运行

OpenResty底层是基于Nginx的,查看OpenResty目录的nginx目录,结构与windows中安装的nginx基本一致:

所以这个里面的nginx和平常的nginx是一样的

1)nginx配置文件
worker_processes 1;
events {
worker_connections 1024;
}
http {
server{
listen 999;
server_name localhost;
location /mapbox/ {
access_by_lua_file "/usr/local/openresty/nginx/lua_script/rule.lua";
proxy_pass https://api.mapbox.com/;
proxy_ssl_server_name on;
}
}
}
2)lua脚本文件(白名单加限流)

通过两个redis的key,map_request_limitation:存放令牌数量,map_request_white_list:白名单列表;白名单的IP,无需限流,只有白名单之外的才需要限流

-- 其实这两个值可以从redis取  甚至可以给每个qrcode设置单独的速率和容积
-- 但如果想监听桶的状态 需要持续的请求, 只有每次请求后才重新计算并更新桶状态 否则桶状态不变
local tokens_per_second = 0.2 -- 生成速率 /s
local max_tokens = 10 -- 最大溶剂 local current_time = ngx.now()
local path = ngx.var.uri
local redis_key = "map_request_limitation"
local redis_key_white_list = "map_request_white_list" local client_ip = ngx.var.remote_addr
-- local redis_key = "path:" .. path -- 连接Redis
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "Redis连接失败: ", err)
return ngx.exit(500)
end
-- 权限校验
local res, err = red:auth("123456")
if not res then
ngx.say("failed to authenticate: ", err)
return
end
-- 发送 Lua 脚本(保证redis原子性操作)
local script = [[ local redis_key = KEYS[1]
local redis_white_list_key = KEYS[2]
local tokens_per_second = tonumber(ARGV[1])
local max_tokens = tonumber(ARGV[2])
local current_time = tonumber(ARGV[3])
local client_ip = ARGV[4] -- ip是否存在列表中
local is_in_whitelist, err = redis.call('sismember', redis_white_list_key, client_ip)
if is_in_whitelist == 1 then
return 1
end -- 获取上次访问时间和令牌数量
local res = redis.call('HMGET', redis_key, 'last_access_time', 'tokens')
local last_access_time
local last_tokens
if res[1] and res[2] then
last_tokens = res[2]
last_access_time = res[1]
end -- 计算时间间隔
local time_passed = current_time - (tonumber(last_access_time) or 0) -- 计算新的令牌数量
last_tokens = last_tokens and tonumber(last_tokens) or max_tokens
local new_tokens = math.min(max_tokens, last_tokens + time_passed * tokens_per_second) -- 判断令牌数量是否足够
if new_tokens >= 1 then
-- 消耗令牌
redis.call('HMSET', redis_key, 'last_access_time', current_time, 'tokens', new_tokens - 1)
return 1
else
return 0
end
]] -- 执行脚本
local result = red:eval(script, 2, redis_key, redis_key_white_list,tokens_per_second, max_tokens,current_time,client_ip) if result == 1 then
-- 成功
ngx.log(ngx.INFO, "成功")
else
-- 令牌不足
ngx.status = ngx.HTTP_TOO_MANY_REQUESTS
ngx.say("OVERLOAD!!!!",result)
return ngx.exit(ngx.HTTP_TOO_MANY_REQUESTS)
end -- 返还redis连接到连接池
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.log(ngx.ERR, err)
end

启动之后当通过这个999端口访问之后,我们在redis里面可以看到以下两个key,白名单可以自行添加,即时生效

nginx做白名单和限流的更多相关文章

  1. nginx访问白名单设置以及根据$remote_addr分发

    在日常运维工作中,会碰到这样的需求:设置nginx的某个域名访问只对某些ip开放,其他ip的客户端都不能访问.达到这样的目的一般有下面两种设置方法:(1)针对nginx域名配置所启用的端口(一般是80 ...

  2. nginx的白名单

    为nginx设置白名单的几个步骤:   第一步:指定能访问的白名单   vim /etc/nginx/ip.conf (如果在公司,记得这里是外网IP,要不然测很久都不知道为什么不行) ;   第二步 ...

  3. nginx限速白名单配置

    在<nginx限制连接数ngx_http_limit_conn_module模块>和<nginx限制请求数ngx_http_limit_req_module模块>中会对所有的I ...

  4. nginx 配置白名单

    在http 模块 增加 geo $remote_addr $ip_whitelist{ default 0; include white_ip.conf; } 在location 模块 增加 (注意i ...

  5. Nginx IP 白名单设置

    1:ip.config 192.168.3.15 1;192.168.3.10 1;192.168.0.8 1; 2:nginx.conf #geoIP的白名单 geo $remote_addr $i ...

  6. nginx配置白名单

    配置如下: http模块: http { include mime.types; default_type application/octet-stream; #log_format main '$r ...

  7. 小白也能看懂的Redis教学基础篇——做一个时间窗限流就是这么简单

    不知道ZSet(有序集合)的看官们,可以翻阅我的上一篇文章: 小白也能看懂的REDIS教学基础篇--朋友面试被SKIPLIST跳跃表拦住了 书接上回,话说我朋友小A童鞋,终于面世通过加入了一家公司.这 ...

  8. 在服务器端对sshd做白名单

    1.添加用户 #useradd aaa #passwd aaa -->输入密码:123456 添加3个用户,bbb和ccc与aaa添加一样 2.添加白名单 #vim /etc/ssd/sshd_ ...

  9. Nginx对同一IP限速限流

    limit_conn_zone是限制同一个IP的连接数,而一旦连接建立以后,客户端会通过这连接发送多次请求,那么limit_req_zone就是对请求的频率和速度进行限制. limit_conn_zo ...

  10. nginx域名访问的白名单配置梳理

    在日常运维工作中,会碰到这样的需求:设置网站访问只对某些ip开放,其他ip的客户端都不能访问.可以通过下面四种方法来达到这种效果:1)针对nginx域名配置所启用的端口(比如80端口)在iptable ...

随机推荐

  1. Python Code_04InputFunction

    代码部分 # coding:utf-8 # author : 写bug的盼盼 # development time : 2021/8/28 6:55 present = input('你想要什么?') ...

  2. ingress nginx 支持的K8S版本以及nginx版本信息

  3. [转帖]内存管理参数zone_reclaim_mode分析

    zone_reclaim_mode 官方解释 调整方法 调整的影响 官方解释 最近在性能优化,看到了zone_reclaim_mode参数,记录备用 zone_reclaim_mode: Zone_r ...

  4. [转帖]DOCKER默认网段和主机网段冲突解决

    https://www.cnblogs.com/yinliang/p/13189334.html 一. docker默认网卡docker0 172.17.0.0可能会与主机冲突,这时候需要修改dock ...

  5. CPU算力提升与实际性能提升的关系

    关于SPEC2006CPU和RedisBenchmark的理解 最近研究过硬件CPU的性能和Redis这样单线程重IO服务 突然想对比一下CPU算力提升占Redis性能提升的比率情况 性能很大程度由C ...

  6. 【转帖】Linux多链路聚合技术

    https://www.jianshu.com/p/dd8587ecf54f 一般而言,在单体结构的操作系统中,一块物理磁盘会接在总线设备上,并经由总线分配 PCI-Bus 号,这个时候一个 bus  ...

  7. [转帖]一起来体验96核心、192线程CPU——第四代AMD EPYC处理器独家测试

    http://k.sina.com.cn/article_1882475282_70344b12027010s1x.html 与第三代EPYC 7003系列处理器相比,新一代EPYC 9004系列处理 ...

  8. [换帖]Linux命令之iconv命令

    一.命令简介   日常工作中我们需要将windows生成的文件上传到Linux系统,有时候会因为编码问题出现显示乱码.例如我上传了一个csv文件到Linux服务器上,默认编码为GB2312,在Linu ...

  9. [转贴]英特尔Sapphire Rapids至强可扩展CPU完整型号爆料与路线图展望

    2022-10-13 15:15· 稿源: cnbeta   腾讯云服务器促销:2核2G首年仅需40元 历史新低   @结城安穗-YuuKi_AnS 刚刚在社交媒体上,分享了与英特尔下一代 Sapph ...

  10. PG数据库异步流复制

    PG数据库异步流复制 背景说明 最近想进行一个数据库高可用课题的研究. 因为之前某种原因,这次选择的是PG数据库. 为了简单起见, 暂时采用PG异步流复制的场景. 这次仅是为了测试, 不考虑高可用绿色 ...