一次生产事故让我学会了 Nginx 限速

前方的路都是坑,只有你踩过,你才知道,经验就是钱。别问公司里,同样敲的代码,为啥别人比你工资高,因为别人踩的坑比你多。

最近,我们生产服务器就出了一次故障。这个故障本来是一个小问题,但是迫于我们没有运维,就只能我们硬着头皮去自己研究摸索。最终发现了问题并解决了它,它就是一个简单的 Nginx 限速问题。

WIFi 限速

事情经过是这样的,一次,我们生产上服务器大半夜的发出了报警信息。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 浏览器下载被限制

360 浏览器下载不超过 1M。

谷歌浏览器下载被限制

谷歌浏览器下载也不超过 1M。其他的我就不在截图了,都被限制了。然后,结果你们都知道了,服务器带宽等都恢复正常。

只有你又当爹又当妈的时候,你才知道这些知识的重要性!

一次生产事故让我学会了 Nginx 限速

: » 一次生产事故让我学会了 Nginx 限速

原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/252771.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论