一、令牌桶算法

image.png

算法思想是:

令牌以固定速率产生,并缓存到令牌桶中;
令牌桶放满时,多余的令牌被丢弃;
请求要消耗等比例的令牌才能被处理;
令牌不够时,请求被缓存。

二、漏桶算法

image.png

算法思想是:

水(请求)从上方倒入水桶,从水桶下方流出(被处理);
来不及流出的水存在水桶中(缓冲),以固定速率流出;
水桶满后水溢出(丢弃)。
这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
从作用上来说,漏桶和令牌桶算法最明显的区别就是是否允许突发流量(burst)的处理,漏桶算法能够强 行限制数据的实时传输(处理)速率,对突发流量不做额外处理;
而令牌桶算法能够在限制数据的平均 传输速率的同时允许某种程度的突发传输。
Nginx按请求速率限速模块使用的是漏桶算法,即能够强行保证请求的实时处理速度不会超过设置的阈值。

三、配置案例

1、limit_conn_zone

1.1nginx配置

  1. http{
  2. limit_conn_zone $binary_remote_addr zone=one:10m;
  3. server
  4. {
  5. ......
  6. limit_conn one 10;
  7. ......
  8. }
  9. }

其中“limit_conn one 10”既可以放在server层对整个server有效,也可以放在location中只对单独的 location有效。 该配置表明:客户端的并发连接数只能是10个。
1.2结果
ab工具20并发去请求nginx,可以看到 Complete requests: 20 Failed requests: 9 (由于nginx配置中一个ip并发连接数为10,而结果中成功数为+1的原因为 计数器 从零 开始 0 所以会 多一个;nginx的日志中也可以看到有9个请求返回503)

2、limit_req_zone

2.1 nginx配置

  1. http{
  2. limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
  3. server
  4. {
  5. ......
  6. limit_req zone=req_one burst=120;
  7. ......
  8. }
  9. }

其中“limit_req zone=req_one burst=120”既可以放在server层对整个server有效,也可以放在location 中只对单独的location有效。
rate=1r/s的意思是每个地址每秒只能请求一次,也就是说令牌桶burst=120一共有120块令牌,并且每 秒钟只新增1块令牌, 120块令牌发完后,多出来的请求就会返回503.。

3、ngx_http_upstream_module

3.1通过官方文档介绍,
该模块有一个参数:max_conns可以对服务端进行限流,可惜在商业版 nginx中才能使用。然而,在nginx1.11.5版本以后,官方已经将该参数从商业版中脱离出来了,也就是说只要我们将生产上广泛使用的nginx1.9.12版本和1.10版本升级即可使用(通过测试可以看到,在旧版本的nginx中,如果加上该参数,nginx服务是无法启动的)。
3.2配置

  1. upstream xxxx{
  2. server 127.0.0.1:8080 max_conns=10;
  3. server 127.0.0.1:8081 max_conns=10;
  4. }

3.3结果
用两台机器各自用ab工具向nginx发送20、30、40个并发请求: 可以看到无论并发多少,成功的请求只有12个,成功的次数会多个2个,同时1.2的测试结果中成功 次数也是+1,这里是两台机器,基于此种考虑,将机器增加至三台,果然成功的次数为13个。
这里得出一个假想,成功的请求数会根据客户端的+1+1(这里只是假设)** 注:还有很重要的几点。max_conns是针对upstream中的单台server的,不是所有;nginx有个参数: worker_processes,max_conns是针对每个worker_processes的;