为了防止恶意攻击,Nginx提供了ngx_http_limit_conn_module来限制并发链接的数量。
ngx_http_limit_conn_module可以根据用户的IP,SERVER_NAME等参数来限制并发数量。
比较经典的示例如下:
# 定义一个限制规则addr,根据用户IP地址$binary_remote_addr匹配,10m的链接池大小 limit_conn_zone $binary_remote_addr zone=addr:10m; # 每个IP并发数量为1,超过则默认返回503, limit_conn addr 1; server { listen 80 default_server; server_name localhost; location =/test_ip{ default_type text/plain; echo remote_add is $remote_addr; echo http_x_forwarded_for is $http_x_forwarded_for; echo clientRealIp is $clientRealIp; } }
但是,$binary_remote_addr不一定用户的真实IP,有可能是通过CDN代理过来的请求,所以添加匹配用户的真实IP的配置
map $http_x_forwarded_for $clientRealIp { ## 没有通过代理,直接用 remote_addr "" $remote_addr; ## 用正则匹配,从 x_forwarded_for 中取得用户的原始IP ~^(?P<firstIP>[0-9\.]+),?.*$ $firstIP; } # 定义一个限制规则addr,根据用户真实IP地址$clientRealIp匹配,10m的链接池大小 limit_conn_zone $clientRealIp zone=addr:10m; # 并发数量为1,超过则默认返回503, limit_conn addr 1; server { listen 80 default_server; location =/test_ip{ default_type text/plain; echo remote_add is $remote_addr; echo http_x_forwarded_for is $http_x_forwarded_for; echo clientRealIp is $clientRealIp; } }
配置完毕,重启Nginx,然后通过JMeter并发测试,会在Nginx的error.log中看到如下信息:
[error] 3744#0: *1955 limiting connections by zone "addr", client: 10.118.27.155, server: localhost, request: "GET /test_ip HTTP/1.1", host: "10.118.27.201" [error] 3744#0: *1956 limiting connections by zone "addr", client: 10.118.27.155, server: localhost, request: "GET /test_ip HTTP/1.1", host: "10.118.27.201"
更多配置请查看官网
Leave a Reply