前方的路都是坑,只有你踩过,你才知道,经验就是钱。别问公司里,同样敲的代码,为啥别人比你工资高,因为别人踩的坑比你多。
最近,我们生产服务器就出了一次故障。这个故障本来是一个小问题,但是迫于我们没有运维,就只能我们硬着头皮去自己研究摸索。最终发现了问题并解决了它,它就是一个简单的 Nginx 限速问题。
事情经过是这样的,一次,我们生产上服务器大半夜的发出了报警信息。CPU、磁盘、带宽都报警,奇了怪了,最近没有活动啊,为什么大晚上的,服务器异常呢?
于是,赶紧爬起来,分析 Nginx 的日志信息,发现有人在进行多线程高并发的下载。这是黑客找到了我们的一个缺点,用多线程下载的方式把我们服务器搞垮了。这得赶紧解决,要不然明天又要喝茶。
- [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.15:8188 ups_resp_time: 0.010 request_time: 0.011 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.16:8188 ups_resp_time: 0.006 request_time: 0.006 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.15:8188 ups_resp_time: 0.013 request_time: 0.013 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.17:8188 ups_resp_time: 0.003 request_time: 0.003 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.18:8188 ups_resp_time: 0.004 request_time: 0.004 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.15:8188 ups_resp_time: 0.012 request_time: 0.013 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.18:8188 ups_resp_time: 0.005 request_time: 0.005 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.16:8188 ups_resp_time: 0.011 request_time: 0.011 - [31/May/2018:00:01:03 -0700] - xxx.ip.addr.xxx GET /download/xttblog.zip HTTP/1.1 - 192.168.100.15:8188 ups_resp_time: 0.447 request_time: 0.759
强大如 CSDN 都在下载时提示禁止使用迅雷进行下载。还有群里一个网友分享的 dl.xabc.io 网站,在并发下载时都会出现故障宕机。
后来我想起来了,必须对下载限速,并且限制多线程下载。有些公司面试中,可能就会问到,如何限制多线程下载?
其实就是服务端根本就不要提供 Content-Length 值。试想一下,如果多线程下载工具得不到文件总大小值,如何分配去分配每个线程需要下载的量呢?不得已,只能通过单线程下载了。
Nginx 中有一个 ngx_http_core_module 模块,该模块中有一个 limit_rate 指令。我们根据它就可以限速,并且配合 ngx_http_limit_conn_module 模块中的 limit_conn 指令可以限制线程数。
http { limit_zone xttblog $binary_remote_addr 10m; ... server { ... location /download/ { ... limit_rate 100k; #限制速度 limit_rate_after 1m; limit_conn xttblog 2; #限制线程 ... } } }
指令 limit_rate 表示设置最高下载速度;指令 limit_rate_after 从下载到你指定的文件大小之后开始限速。但是这个设置是限制的是每一个连接的下载速度,所以如果一个用户打开了多个连接下载,那么它的下载速度就能达到单个连接的限速乘以连接数。
所以,limit_zone 指令定义一个叫“xttblog”的记录区,总容量为 10M,以变量 $binary_remote_addr 作为会话的判断基准(即一个地址一个会话)。限制 /download/ 目录下,一个会话只能进行一个连接。简单点,就是限制 /download/ 目录下,一个 IP 只能发起 2 个连接,多过 2 个,一律 503。
配置完后,重启 Nginx,迅雷下载不超过 1M,被限制。
360 浏览器下载不超过 1M。
谷歌浏览器下载也不超过 1M。其他的我就不在截图了,都被限制了。然后,结果你们都知道了,服务器带宽等都恢复正常。
只有你又当爹又当妈的时候,你才知道这些知识的重要性!
: » 一次生产事故让我学会了 Nginx 限速
原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/252771.html