关于nginx上的limit_req_zone模块限流使用与geo与map的白名单配置

今天正好是五一假期 记录一下前几天关于开发中遇到的nginx上的问题

之前接口被人扒了 访问量激增 之前的同事配置了一个nginx上的配置来解决 如下

1.在nginx的http模块下面加上下面的语句

limit_req_zone $binary_remote_addr zone=test:10m rate=10r/s;

说明:
区域名称为test,这个名称自定义即可,占用空间大小为10m,平均处理的请求频率不能超过每秒十次。

binary_remote_addr是remote_addr(客户端IP)的二进制格式,固定占用4个字节,这里官方文档建议使用$binary_remote_addr,原因为保持内存存储大小相等。

2.在nginx的server模块下面加上下面的语句

location / {
    
    
        	limit_req zone=test burst=20 nodelay ;

说明:
burst表示在超过设定的处理速率后能额外处理的请求数。当rate=10r/s时,将1s拆成10份,即每100ms可处理1个请求。

nodelay针对的是burst 参数,指定了过多请求被延迟的delay限制。默认值为零,即延迟所有过多的请求。

因此,burst往往结合nodelay一起使用。


当时同事就是用这个方法解决了线上的问题,但是这样导致出了另一个问题,就是这个接口还有其他单位的同事在使用,因为上面的配置是针对全部IP去进行的,所以其他单位的同事就来反馈问题了,于是就有了下面的方法

使用与geo与map的白名单配置

1.在nginx.conf的http部分中配置白名单:

geo $limit {
    
    
    default 1;
    127.0.0.1 0;
}
map $limit $limit_key {
    
    
    0 "";
    1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;

说明:
geo对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。
map将limit转换为limit_key,如果是limit是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。
limit_req_zone限流的key不再使用binary_remote_addr,而是$limit_key来动态获取值。如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流;若不是白名单,将会对客户端IP进行限流。

按照以上的方法配置完了以后,我们在测试环境没有问题,于是开始上线


!!!注意!!!

我们在上线修改完配置后,出现了另一个问题,这个问题很蠢,但是确实很容易发生,就是nginx的缓存问题

我们在修改完配置文件后,使用 ./nginx -s reload 对nginx进行重启,发现没有效果,于是开始排查,配置与测试环境一模一样,于是继续修改,加上了access.log,想看一下日志,结果access.log修改完后重启nginx也没生效,access.log文件被创建了,但是没有日志打印上去。

最后的解决方案是使用stop停止nginx服务,再重新启动,问题完美解决

下面把nginx使用到的指令贴到下面

./nginx:启动nginx
./nginx -s stop:关闭nginx
./nginx -s reload:重新加载配置
./nginx -t:检测配置文件是否正常

猜你喜欢

转载自blog.csdn.net/qq_33525941/article/details/124532214