Nginx限速模块分为哪几种?按请求速率限速的burst和nodelay参数是什么意思?漏桶算法和令牌桶算法究竟有什么不同?本文将带你一探究竟。我们会通过一些简单的示例展示Nginx限速模块是如何工作的,然后结合代码讲解其背后的算法和原理。
核心算法在探究Nginx限速模块之前,我们先来看看网络传输中常用两个的流量控制算法:漏桶算法和令牌桶算法。这两只“桶”到底有什么异同呢?
漏桶算法(leaky bucket)漏桶算法(leaky bucket)算法思想如图所示:
一个形象的解释是:
水(请求)从上方倒入水桶,从水桶下方流出(被处理);
来不及流出的水存在水桶中(缓冲),以固定速率流出;
水桶满后水溢出(丢弃)。
这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
算法思想如图所示:
算法思想是:
令牌以固定速率产生,并缓存到令牌桶中;
令牌桶放满时,多余的令牌被丢弃;
请求要消耗等比例的令牌才能被处理;
令牌不够时,请求被缓存。
相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
从作用上来说,漏桶和令牌桶算法最明显的区别就是是否允许突发流量(burst)的处理,漏桶算法能够强行限制数据的实时传输(处理)速率,对突发流量不做额外处理;而令牌桶算法能够在限制数据的平均传输速率的同时允许某种程度的突发传输。
Nginx按请求速率限速模块使用的是漏桶算法,即能够强行保证请求的实时处理速度不会超过设置的阈值。
Nginx限速模块Nginx主要有两种限速方式:按连接数限速(ngx_http_limit_conn_module)、按请求速率限速(ngx_http_limit_req_module)。我们着重讲解按请求速率限速。
按连接数限速按连接数限速是指限制单个IP(或者其他的key)同时发起的连接数,超出这个限制后,Nginx将直接拒绝更多的连接。这个模块的配置比较好理解,详见ngx_http_limit_conn_module官方文档。
按请求速率限速按请求速率限速是指限制单个IP(或者其他的key)发送请求的速率,超出指定速率后,Nginx将直接拒绝更多的请求。采用leaky bucket算法实现。为深入了解这个模块,我们先从实验现象说起。开始之前我们先简单介绍一下该模块的配置方式,以下面的配置为例:
http { limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; ... server { ... location /search/ { limit_req zone=mylimit burst=4 nodelay; }使用limit_req_zone关键字,我们定义了一个名为mylimit大小为10MB的共享内存区域(zone),用来存放限速相关的统计信息,限速的key值为二进制的IP地址($binary_remote_addr),限速上限(rate)为2r/s;接着我们使用limit_req关键字将上述规则作用到/search/上。burst和nodelay的作用稍后解释。
使用上述规则,对于/search/目录的访问,单个IP的访问速度被限制在了2请求/秒,超过这个限制的访问将直接被Nginx拒绝。
实验1——毫秒级统计我们有如下配置:
... limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; server { location / { limit_req zone=mylimit; } } ...上述规则限制了每个IP访问的速度为2r/s,并将该规则作用于跟目录。如果单个IP在非常短的时间内并发发送多个请求,结果会怎样呢?
# 单个IP 10ms内并发发送6个请求 send 6 requests in parallel, time cost: 2 ms HTTP/1.1 503 Service Temporarily Unavailable HTTP/1.1 200 OK HTTP/1.1 503 Service Temporarily Unavailable HTTP/1.1 503 Service Temporarily Unavailable HTTP/1.1 503 Service Temporarily Unavailable HTTP/1.1 503 Service Temporarily Unavailable end, total time cost: 461 ms