Nginx 常用配置
1.限速 Rate Limiting
基本原理
使用了水池算法,即水池的流入水量代表进入的请求,水池的流出水量代表转发请求给应用程序;当设置了某个水池的容量后,如果在某段时间,流入的水量比较大,超过了流出的水量,将导致水池中的水溢出;溢出的水即代表被拒绝的请求;
实现办法
基本设置
limit_req_zone 表示限速区域
- 第一个参数表示限速匹配条件的关键字,此处为二进制的IP地址 $binary_remote_addr;
- 第二个参数表示限速区域名称,此处为 mylimi,冒号后面表示用来存储请求数据的内存空间大小,此处设置为 10MB(每 MB 大约可以存储 16000 个二进制 IP 地址,因此 10 MB 大约可以存储 16万个IP地址);
- 第三个参数 rate 表示限制的速度,此处为 10r/s,表示每秒10个请求,也即每 100 毫秒 1 个请求;
1 |
|
应对突发
当第二个请求到达的时间,距离上一个请求的时间少于100毫秒时,Nginx 将返回 503 的响应;为了解决突发的高峰访问的场景,引入了另外两个控制限速的关键字,分别如下:
1 |
|
burst 表示增加一个等待队列,当下一个请求距离上一个请求少于 100 毫秒时,就先将其放入队列中;此处 burst=20 表示同时最多可以有20个请求在排队;如果某个请求进来时,前面已经 20 个请求在排除,则该请求将被拒绝;
免等待队列
虽然 burst 为突发的访问高峰的请求增加了一个缓冲的机制,但它的缺点是让响应变慢了,因为有些请求,例如队列中的第 20 个请求,将等候 2 秒钟的时间后,再会转发给应用程序进行响应;为了避免等待,引入了 nodelay 关键字,它表示请求到达后,将立即被转发给应用程序进行处理,不需等待,但是仍然会占用队列中的一个等待名额;这意味着如果某个时刻同一个 IP 同时发送 21 个请求,则前面 20 个请求将直接转发给应用程序处理,而第 21 个将被拒绝;队列中占用的名额每 100 毫秒释放一个;
两阶段限速
1 |
|
此处仍然建立了能够应对额外 12 个突发请求的队列,但是增加了 delay 参数,并将值设置为 8,它表示队列中的前 8 个请求使用免等待策略,而剩下的 4 个请求需要等待;此时如果进行第 13 个请求,将被拒绝;
高级设置
白名单
- 先通过 geo 指令建立了一份白名单,普通请求的 $limit 值被默认设置为为 1,指定 IP 段的请求则被设置为 0 ;
- 再通过 map 指令将 $limit 值为 1 的请求的 $limit_key 属性值设置为 $binary_remote_addr,将$limit 值为 0 的请求设置为空字符串;
- 最后在 limit_req_zone 指令中,$limit_key 的值若为空字符串的请求,将被忽略,不会施加限制;
1 |
|
单个路径使用多个 limit_req
当使用多个 limit_req 时,如果一个请求被多个 limit_req 同时匹配到,则最长 delay 时间的那个将生效;如果被任意一个 limit_req 拒绝,则请求将拒绝;
1 |
|
其他配置项
日志
被延误的请求将记录在 warn 日志中;被拒绝的请求将请求在 error 日志中;
1 |
|
但是可以手工指定日志等级,以下示例即为指定日志等级为 warn;
1 |
|
当请求被拒绝时,默认是返回 503 的错误码,如有需要,可以手工设置,以下示例设置为 444
1 |
|
如果某个路径需要拒绝所有请求,则可以通过设置 deny all 实现;
1 |
|