【nginx】 实现限流

前言

好久不见,还算为时不晚。最近一个月经历了工作的调整,技术栈从Java转向了Go和Python, 工作显得更忙了些,但是还是希望持续输出滴。最近做的产品,领导说要加一个限流功能,下面来看看如何实现。

正文

实现限流功能,限制并发数量,保护上游应用不被过多用户请求压垮,否则接下来的事情就会让人很emo了。

nginx实现限流

初步想法用最基本的计数来实现,后面觉得得改代码还得发版,这个时候还是尽量不要动代码了,发现nginx可以实现该功能。

并发限制

限制同一时间请求连接数量,使用ngx_http_limit_conn_module ,分为限制单IP和服务两种场景,使用limit_conn_zone和limit_conn 指令进行配置。

限制单IP并发数量
# 在http 中配置
http {
# 格式定义 limit_conn_zone key zone=name:size;
limit_conn_zone $binary_remote_addr  zone=mylimit:10m;
...
   server {
      listen 8080;
      # 在location中配置 最大连接数为5个
	    location /xxx{
		     limit_conn mylimit 5;
		     ...
	     }
     }
}

说明:

  • limit_conn_zone 定义一个会话块,记录会话状态信息;
  • zone=mylimit:10m 会话块叫做mylimit,内存容量为10M;
  • $binary_remote_addr 表示请求客户端的IP地址,作为会话请求限制的key,限制同一IP地址的请求连接数;
  • limit_conn mylimit 5 会话块最大连接数为5个,当超过数量限制后,对于后续请求默认返回503 response
    code,也可以使用limit_conn_status 自定义返回的状态码;
限制单主机服务并发数量
http {

limit_conn_zone $server_name zone=serverlimit:10m;
...
   server {
  	 listen 8081;
  	 server_name: xxx;
     location /xxx{
		     limit_conn serverlimit 5;
		     ...
	     }
     }
}

说明:

  • limit_conn_zone 定义一个会话块,记录会话状态信息;
  • zone=serverlimit:10m 会话块叫做serverlimit,内存容量为10M;
  • $server_name 虚拟主机作为会话请求限制的key,限制同一虚拟主机的请求连接数;
  • limit_conn serverlimit 5 会话块最大连接数为5个,当超过数量限制后,对于后续请求默认返回503
    response code,也可以使用limit_conn_status 自定义返回的状态码;

速率限制

限制单位时间内的请求数,使用ngx_http_limit_req_module ,采用漏桶算法,使用limit_req_zone和limit_req 指令进行配置

http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
...
   server {
  	 listen 8081;
  	 server_name: xxx;
     location /xxx {    
         # 格式定义 limit_req zone=name [burst=number] [nodelay];
		     limit_req zone=mylimit burst=5 nodelay;
		     ...
	     }
     }
}

说明:

  • llimit_req_zone 定义一个请求会话块,记录会话状态信息;
  • zone=mylimit:10m 会话块叫做serverlimit,内存容量为10M;
  • $binary_remote_addr 同一客户端IP地址作为会话请求限制的key,限制同一IP地址的请求速度;
  • rate=2r/s 1s允许处理2个请求,nginx实际上以ms为粒度来跟踪请求信息,所以可以理解为500毫秒内只允许通过1个请求,从501毫秒开始才允许通过第二个请求。
  • limit_req zone=mylimit 应用上述http作用域的限流配置
  • burst 设置缓冲区大小,当在单位时间内有超过上述速度的请求过来时(突发流量),可以先放到这个缓冲区内;此缓冲区可以支持存放5个多余请求;
  • nodelay 让缓冲区的请求立即处理,如果不加此参数,缓冲区的请求还是按照原来的2r/s的速度处理,处理完缓冲区的5个请求需要2.5s,加了该配置后,缓冲区的请求可以被立即处理,这样请求数超过burst+rate之后多余的请求会立刻被拒绝处理,就不会有一些tcp连接请求等待。

限流效果

用Apifox或者ab(apachebench)测试并发超过限制的效果(也可通过nginx日志查看响应情况):
在这里插入图片描述
在这里插入图片描述

注意

  • 对某个IP 设置限流时考虑Nginx location匹配的优先级,避免设置了未生效
  • 并发限制的两种限制可以同时使用
  • limit_conn_log_level 和 limit_req_log_level 提供了日志功能

疑问

限制了并发数量,有时候用工具测试时会出现超过并发数量测试通过的情况 ,还没有搞明白,希望路过的朋友们给些指导 Thanks♪(・ω・)ノ

参考链接

https://juejin.cn/post/7121903842102509581?share_token=fed0ddaa-bcf8-4844-b4a2-0a906c98ae38
https://www.cnblogs.com/chenpingzhao/p/4971308.html
http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

小结

记录工作日常,还是一个努力搬砖的大朋友~

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的大白啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值