Nginx配置限流

一、常规普通配置

## 用户的 IP 地址 $binary_remote_addr 作为 Key,每个 IP 地址最多有 50 个并发连接
## 你想开 几千个连接 刷死我? 超过 50 个连接,直接返回 503 错误给你,根本不处理你的请求了
limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:10m ;
limit_conn  TotalConnLimitZone  50;
limit_conn_log_level notice;
 
## 用户的 IP 地址 $binary_remote_addr 作为 Key,每个 IP 地址每秒处理 10 个请求
## 你想用程序每秒几百次的刷我,没戏,再快了就不处理了,直接返回 503 错误给你
limit_req_zone $binary_remote_addr zone=ConnLimitZone:10m  rate=10r/s;
limit_req_log_level notice;
 
## 具体服务器配置
server {
    listen   80;
    location ~ \.php$ {
                ## 最多 5 个排队, 由于每秒处理 10 个请求 + 5个排队,你一秒最多发送 15 个请求过来,再多就直接返回 503 错误给你了
        limit_req zone=ConnLimitZone burst=5 nodelay;
 
        ...
    }   
 
}

二、改进配置

  很多时候,我们的网站不是简单的 普通用户IE浏览器 , 你的服务器 的结构, 考虑到网络访问速度问题,我们中间可能会有各种 网络加速(CDN)。

  普通用户浏览器 —–> 360网站卫士加速(CDN,360防 CC,DOS攻击) ——> 阿里云加速服务器(我们自己建的CDN,阿里云盾) —-> 源服务器(PHP 程序部署在这里,iptables, nginx 安全配置)。

  网站中间经历了好几层的透明加速和安全过滤, 这种情况下,我们就不能用上面的“普通配置”。因为上面基于 源IP的限制 结果就是,我们把 360网站卫士 或者 阿里云盾 给限制了,因为这里“源IP”地址不再是 普通用户的IP,而是中间 网络加速服务器 的IP地址。我们需要限制的是 最前面的普通用户,而不是中间为我们做加速的 加速服务器。

 当一个 CDN 或者透明代理服务器把用户的请求转到后面服务器的时候,这个 CDN 服务器会在 Http 的头中加入 一个记录X-Forwarded-For : 用户IP, 代理服务器IP。

 X-Forwarded-For : 用户IP, 代理服务器1-IP, 代理服务器2-IP, 代理服务器3-IP, ….

 可以看到经过好多层代理之后, 用户的真实IP 在第一个位置, 后面会跟一串 中间代理服务器的IP地址,从这里取到用户真实的IP地址,针对这个 IP 地址做限制就可以了。

## 通过 map 指令,我们为 nginx 创建了一个变量 $clientRealIp ,这个就是 原始用户的真实 IP 地址, 
	## 不论用户是直接访问,还是通过一串 CDN 之后的访问,我们都能取得正确的原始IP地址
	map $http_x_forwarded_for  $clientRealIp {
        ## 没有通过代理,直接用 remote_addr
		""  $remote_addr;  
        ## 用正则匹配,从 x_forwarded_for 中取得用户的原始IP
        ## 例如   X-Forwarded-For: 202.123.123.11, 208.22.22.234, 192.168.2.100,...
        ## 这里第一个 202.123.123.11 是用户的真实 IP,后面其它都是经过的 CDN 服务器
		~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
	}
	
	## 针对原始用户 IP 地址做限制
	limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ;
	## 每个 IP 地址最多有 50 个并发连接,超过 50 个连接,直接返回 503 错误
	limit_conn  TotalConnLimitZone  50;
	limit_conn_log_level notice;

	## 针对原始用户 IP 地址做限制,每个 IP 地址每秒处理 80 个请求,再快了就不处理了,直接返回 503 错误
	limit_req_zone $clientRealIp zone=ConnLimitZone:20m  rate=80r/s;
	limit_req_log_level notice;

		
	
	
	server {
		# 服务器端口使用443,开启ssl, 这里ssl就是上面安装的ssl模块
		listen       443 ssl;
		# 域名,多个以空格分开
		server_name  www.zhqwfj.xyz;
		
		# ssl证书地址
		ssl_certificate     /usr/local/nginx/cert/ssl.pem;  # pem文件的路径
		ssl_certificate_key  /usr/local/nginx/cert/ssl.key; # key文件的路径
		
		# ssl验证相关配置
		ssl_session_timeout  5m;    #缓存有效期
		ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;    #加密算法
		ssl_protocols TLSv1 TLSv1.1 TLSv1.2;    #安全链接可选的加密协议
		ssl_prefer_server_ciphers on;   #使用服务器端的首选算法

		location / {
			## 最多 5 个排队, 由于每秒处理 80 个请求 + 5个排队,你一秒最多发送 85 个请求过来,再多就直接返回 503 错误给你了
			limit_req zone=ConnLimitZone burst=5 nodelay;
			...
		}
    }
	

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值