nginx中基于jsessionid的限速策略
公司某系统经常出现短时间内同一用户大量并发访问的情况,疑似爬虫行为,该行为经常导致应用节点连接超时频发的问题。由于业务代码层对用户的限速和限制并发的能力有限,因此决定采用F5后添加nginx反向代理,通过nginx的limit_req_zone模块进行限速,通过limit_conn_zone模块来进行限制并发。
首先利用nginx的内置变量$http_x_forwarded_for获取远端的访问IP,以该变量来进行访问限速。具体访问策略如下:
▼▼▼
http {
include mime.types;
default_type application/octet-stream;
......(常规配置忽略)
#gzip on;
#限速策略
limit_req_zone $http_x_forwarded_for zone=req:100m rate=10r/m;
limit_conn_zone $http_x_forwarded_for zone=reqconn:100m;
upstream shsnc {
sticky;
server IP:PORT;
server IP:PORT;
server IP:PORT;
}
server {
listen 80;
......(常规配置忽略)
#仅对访问频繁的页面加以限速,aa表示页面URL的关键字段)
location ~ .*(aa|bb).* {
proxy_pass http://shsnc;
limit_req zone=reqzone burst=5;
limit_conn reqconn 10;
}
}
由于用户是通过统一的出口IP来访问业务,以上配置仅对出口IP限速,无法对单个用户访问进行限速,因此导致用户访问比较多时,个别用户出现无法访问业务的情况。因此,改用$http_cookie的方式来进行限速。经过查看,发现http_cookie变量中的信息量过多,格式如下所示:
▼▼▼
JSESSIONID=xxxxxxxxxxxxxxxxxxxxxxxx;
Hm_lvt_fxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
BIGipxxxxxxxxxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxx;
route=xxxxxxxxxxxxxxxxxxxxxxxxxxx;
从上面的格式分析,使用JSESSIONID的值去进行限速比较合理。因此,需要从http_cookie变量中截取JSESSIONID的值作为限速的依据。最终确定方案如下:
▼▼▼
http {
include mime.types;
default_type application/octet-stream;
......(常规配置忽略)
#gzip on;
#限速策略
limit_req_zone $jsvalue zone=req:100m rate=10r/m;
limit_conn_zone $jsvalue zone=reqconn:100m;
upstream shsnc {
sticky;
server IP:PORT;
server IP:PORT;
server IP:PORT;
}
server {
listen 80;
......(常规配置忽略)
#截取设置限速jsessionid字符串
set $jsvalue "";
if ( $http_cookie ~* "JSESSIONID=(.+?)(?=;)" ) {
set $jsvalue $1;
}
#仅对访问频繁的页面加以限速,aa表示页面URL的关键字段)
location ~ .*(aa|bb).* {
proxy_pass http://shsnc;
limit_req zone=reqzone burst=5;
limit_conn reqconn 10;
}
}
最终,通过截取jsessionid的值到达了限速的策略,也解决了内网用户通过统一出口IP访问业务相应影响的问题。
更多精彩干货分享
点击下方名片关注
IT那活儿
IT那活儿
不管IT什么活儿,干就完了。
Official Account