Nginx限流-速率实现
控制速率
控制速率的方式之一就是采用漏桶算法。
(1)漏桶算法實現控制速率限流
漏桶(Leaky Bucket)算法思路很簡單,水(請求)先進入到漏桶里,漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),然后就拒絕請求,可以看出漏桶算法能強行限制數據的傳輸速率.示意圖如下:
(2)nginx的配置
配置示意圖如下:
修改/usr/local/openresty/nginx/conf/nginx.conf:
user root root; worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;#cachelua_shared_dict dis_cache 128m;#限流設置limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;location /update_content {content_by_lua_file /root/lua/update_content.lua;}location /read_content {#使用限流配置limit_req zone=contentRateLimit;content_by_lua_file /root/lua/read_content.lua;}} }配置說明:
binary_remote_addr 是一種key,表示基于 remote_addr(客戶端IP) 來做限流,binary_ 的目的是壓縮內存占用量。
zone:定義共享內存區來存儲訪問信息, contentRateLimit:10m 表示一個大小為10M,名字為contentRateLimit的內存區域。1M能存儲16000 IP地址的訪問信息,10M可以存儲16W IP地址訪問信息。
rate 用于設置最大訪問速率,rate=10r/s 表示每秒最多處理10個請求。Nginx 實際上以毫秒為粒度來跟蹤請求信息,因此 10r/s 實際上是限制:每100毫秒處理一個請求。這意味著,自上一個請求處理完后,若后續100毫秒內又有請求到達,將拒絕處理該請求.我們這里設置成2 方便測試。
測試:
重新加載配置文件
cd /usr/local/openresty/nginx/sbin./nginx -s reload訪問頁面:http://192.168.211.132/read_content?id=1 ,連續刷新會直接報錯。
(3)處理突發流量
上面例子限制 2r/s,如果有時正常流量突然增大,超出的請求將被拒絕,無法處理突發流量,可以結合 burst 參數使用來解決該問題。
例如,如下配置表示:
上圖代碼如下:
server {listen 80;server_name localhost;location /update_content {content_by_lua_file /root/lua/update_content.lua;}location /read_content {limit_req zone=contentRateLimit burst=4;content_by_lua_file /root/lua/read_content.lua;} }burst 譯為突發、爆發,表示在超過設定的處理速率后能額外處理的請求數,當 rate=10r/s 時,將1s拆成10份,即每100ms可處理1個請求。
此處,burst=4 ,若同時有4個請求到達,Nginx 會處理第一個請求,剩余3個請求將放入隊列,然后每隔500ms從隊列中獲取一個請求進行處理。若請求數大于4,將拒絕處理多余的請求,直接返回503.
不過,單獨使用 burst 參數并不實用。假設 burst=50 ,rate依然為10r/s,排隊中的50個請求雖然每100ms會處理一個,但第50個請求卻需要等待 50 * 100ms即 5s,這么長的處理時間自然難以接受。
因此,burst 往往結合 nodelay 一起使用。
例如:如下配置:
server {listen 80;server_name localhost;location /update_content {content_by_lua_file /root/lua/update_content.lua;}location /read_content {limit_req zone=contentRateLimit burst=4 nodelay;content_by_lua_file /root/lua/read_content.lua;} }如上表示:
平均每秒允許不超過2個請求,突發不超過4個請求,并且處理突發4個請求的時候,沒有延遲,等到完成之后,按照正常的速率處理。
如上兩種配置結合就達到了速率穩定,但突然流量也能正常處理的效果。完整配置代碼如下:
user root root; worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/octet-stream;#cachelua_shared_dict dis_cache 128m;#限流設置limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;location /update_content {content_by_lua_file /root/lua/update_content.lua;}location /read_content {limit_req zone=contentRateLimit burst=4 nodelay;content_by_lua_file /root/lua/read_content.lua;}} }測試:如下圖 在1秒鐘之內可以刷新4次,正常處理。
但是超過之后,連續刷新5次,拋出異常。
?
總結
以上是生活随笔為你收集整理的Nginx限流-速率实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 并发介绍
- 下一篇: Nginx限流-并发量限流配置