最近我的一个项目刚刚上线(日PV > 500W),流量突然之间很大,但是由于我们前期仅仅只是想小范围测试,所以没有准备足够的服务器资源,导致整个应用的访问均变得很慢,最主要的是我们的应用需要从服务器端向多个第三方发起多次请求,而每一次请求都会需要很长的时间,所以,整个应用几乎就到了不能使用的地步了。

排查原因之后,我们的服务器完全没有问题,而问题就是出在了当我们向第三方发起请求之后,第三方需要5分钟左右的时间才能给出结果,这个时候我们前端没有做任何的过滤,这使得有了12406效应,就是我们不出结果,导致前端的用户就一直的试这么一个恶性循坏,临时性的想到的一个办法就是我在我们的应用服务器前端再加一台服务器,若在短时间内,请求次数超过某个阈值,我就直接拒绝请求,使用了 Nginxngx_http_limit_req_module 模块。

/etc/nginx/nginx.conf 文件中,加入如下代码:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=20r/s;

    ...
}

上面这一行的作用是:

  • 定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
  • 以$binary_remote_addr 为key,限制平均每秒的请求为20个,
  • 1M能存储16000个状态,rete的值必须为整数,
  • 如果限制两秒钟一个请求,可以设置成30r/m

然后在我们的 server 中添加如下代码:

server {
    limit_req zone=one burst=5;
    ...
}

作用为:

  • 限制每ip每秒不超过20个请求,漏桶数burst为5
  • brust的意思就是,如果第1秒、2,3,4秒请求为19个,
  • 第5秒的请求为25个是被允许的。
  • 但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。
  • nodelay,如果不设置该选项,严格使用平均速率限制请求数,
  • 第1秒25个请求时,5个请求放到第2秒执行,
  • 设置nodelay,25个请求将在第1秒执行。

标签: 服务器, nginx

评论已关闭