一次限流引发的思考及nginx限流实现
前言:
nginx现在应用越来越广,nginx不仅可以做七层代理,也可以做四层代理,随着业务人数的增多,nginx处理请求的能力也是越来越好,但是后端的请求,对数据库的压力就会增大,所以当用户请求数量过大时,避免对数据库造成毁灭性的影响,只有对nginx进行降级处理。比如限流,或者增加tomcat应用,扩大内存等等,这篇文章主要是讲一些nginx限流的配置参考。
限流主要是看怎么限流,一般是限制访问请求数,不同系统的访问请求数不同,经查资料,可以查看nginx的每秒的请求数,作为参考。
nginx status 需要用到nginx自身的模块with-http_stub_status_module,这个可以用nginx -V来检查模块使用情况(nginx -v只显示nginx版本,而nginx -V 不仅显示版本号,还显示使用的模块)
1. nginx 配置
location /status { stub_status on; access_log off; #allow 127.0.0.1;允许哪个ip可以访问 }
2. nginx -s reload 重启nginx
浏览器输入:http://localhost/status
Active connections: 649 server accepts handled requests 76085213 76085213 218901053 Reading: 0 Writing: 59 Waiting: 590
第1列:当前与http建立的连接数,包括等待的客户端连接:649
第2列:
接受的客户端连接总数目:76085213
处理的客户端连接总数目:76085213
客户端总的请求数目:218901053
第3列:
当前,nginx读请求连接
当前,nginx写响应返回给客户端
目前有多少空闲客户端请求连接
注:红色部分是要特别注意的情况数目,你刷新页面,可以看到这个数值请求情况,这个数值就是nginx总的请求数,你每秒刷新一次,能大概算出每秒的请求数量
3,配置限流
限流分两种,一种是限制ip的的并发请求数,一种是限制每秒请求处理数
1)限制ip的并发请求数:
ngx_http_limit_conn_module 模块 这个模块依赖realIp模块取到的真实ip
一般nginx会放置到架构的最前端,相当于是请求先到nginx,nginx直接反向代理到具体的tomcat,这种情况下realip模块可以获取到客户端最真实的ip
另一种是http请求先请求到F5机器,然后分发到nginx,最后nginx再反向代理到具体的tomcat服务器
这种情况下,nginx获取到的ip其实是F5的ip,不是客户端的真实ip
2)限制每秒请求处理数:
ngx_http_limit_req_module 模块,这个模块也依赖于realIp模块取到的真实ip
模块原理实现的漏斗算法,200r/s,是最后的一个平均的效果,逐步平滑。
算法介绍:https://baike.baidu.com/item/leaky%20bucket/5639070
将下面代码配置到http模块中
proxy_intercept_errors on;
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=200r/s;
limit_conn_status 503; #超出限制时,返回状态码
location模块中增加 limit_req zone=mylimit nodelay;
burst默认等于0
• nodelay 对burst中的请求不再采取延时处理的做法,而是立刻处理。
中200代表的就是每秒的请求数量,这个值参考的就是status中的请求数量
注意:限流方案配置后,会出现,已经登录的用户,再次发送请求的时候,会出现503错误,最好跟业务沟通之后再上限流方案。