Nginx流量控制及白名單實現(xiàn)
流量限制 (rate-limiting),是Nginx中一個非常實用,卻經(jīng)常被錯誤理解和錯誤配置的功能。我們可以用來限制用戶在給定時間內(nèi)HTTP請求的數(shù)量。請求,可以是一個簡單網(wǎng)站首頁的GET請求,也可以是登錄表單的 POST 請求。流量限制可以用作安全目的,比如可以減慢暴力密碼破解的速率。通過將傳入請求的速率限制為真實用戶的典型值,并標(biāo)識目標(biāo)URL地址(通過日志),還可以用來抵御 DDOS 攻擊。更常見的情況,該功能被用來保護上游應(yīng)用服務(wù)器不被同時太多用戶請求所壓垮。
以下將會介紹Nginx的 流量限制 的基礎(chǔ)知識和高級配置,”流量限制”在Nginx Plus中也適用。
1、Nginx如何限流
Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),該算法在通訊和分組交換計算機網(wǎng)絡(luò)中廣泛使用,用以處理帶寬有限時的突發(fā)情況。就好比,一個桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水將會溢出;同樣,在請求處理方面,水代表來自客戶端的請求,水桶代表根據(jù)”先進先出調(diào)度算法”(FIFO)等待被處理的請求隊列,桶底漏出的水代表離開緩沖區(qū)被服務(wù)器處理的請求,桶口溢出的水代表被丟棄和不被處理的請求。
2、配置基本的限流
準(zhǔn)備兩臺機器,關(guān)閉防火墻和selinux
localhost | Roucky_linux9.4 | 192.168.226.20 |
localhost | Roucky_linux9.4 | 192.168.226.21 |
都使用nginx官方源下載nginx并啟動
sudo tee /etc/yum.repos.d/nginx.repo << 'EOF' [nginx-stable] name=nginx stable repo baseurl=https://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key [nginx-mainline] name=nginx mainline repo baseurl=https://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key EOF
yum install -y nginx systemctl enable --now nginx
這里還準(zhǔn)備了訪問自動測試的代碼,使用go語言編寫
package main import ( "fmt" "io" "net/http" "time" ) // ANSI color codes const ( RedColor = "\033[31m" GreenColor = "\033[32m" YellowColor = "\033[33m" ResetColor = "\033[0m" ) // 記錄成功、失敗、無法響應(yīng)以及服務(wù)暫時不可用(503)的請求數(shù)量 var successCount int var failureCount int var unresponsiveCount int var tempUnavailableCount int // 新增變量來跟蹤503 Service Unavailable狀態(tài)的請求數(shù)量 // makeRequest 向給定的 URL 發(fā)送一個 GET 請求,并根據(jù)響應(yīng)的成功與否以不同顏色打印出響應(yīng)狀態(tài)和所花費的時間。 func makeRequest(url string, attempt int) { startTime := time.Now() resp, err := http.Get(url) elapsedTime := time.Since(startTime) if err != nil { // 如果因為網(wǎng)絡(luò)問題或服務(wù)器問題導(dǎo)致請求失敗,我們將其計為“無法響應(yīng)” fmt.Printf("[%d] %sRequest unresponsive: %s %.4f seconds%s\n", attempt, RedColor, err, elapsedTime.Seconds(), ResetColor) unresponsiveCount++ return } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { fmt.Printf("Error closing response body: %s\n", err) } }(resp.Body) color := GreenColor if resp.StatusCode == 503 { color = YellowColor tempUnavailableCount++ // 對返回503狀態(tài)碼的請求進行統(tǒng)計 } else if resp.StatusCode != 200 { color = RedColor failureCount++ } else { successCount++ } // 根據(jù)狀態(tài)碼,以對應(yīng)的顏色打印響應(yīng)狀態(tài)碼和耗時 fmt.Printf("[%d] %s%d %.4f seconds%s\n", attempt, color, resp.StatusCode, elapsedTime.Seconds(), ResetColor) } func main() { url := "http://192.168.226.21" totalAttempts := 1000 startTime := time.Now() for attempt := 1; attempt <= totalAttempts; attempt++ { makeRequest(url, attempt) } totalElapsedTime := time.Since(startTime) successRate := (float64(successCount) / float64(totalAttempts)) * 100 failureRate := (float64(failureCount) / float64(totalAttempts)) * 100 unresponsiveRate := (float64(unresponsiveCount) / float64(totalAttempts)) * 100 tempUnavailableRate := (float64(tempUnavailableCount) / float64(totalAttempts)) * 100 // 計算503狀態(tài)碼比率 fmt.Printf("%sTotal elapsed time: %.4f seconds%s\n", ResetColor, totalElapsedTime.Seconds(), ResetColor) fmt.Printf("成功率: %.2f%%, 失敗率: %.2f%%, 無法響應(yīng)的請求比: %.2f%%, 服務(wù)暫時不可用請求比率(503): %.2f%%\n", successRate, failureRate, unresponsiveRate, tempUnavailableRate) }
實驗開始前進行訪問1000次測試耗時和成功率
在192.168.226.20主機操作
“流量限制”配置兩個主要的指令,limit_req_zone
和limit_req
,如下所示:
在http模塊里配置
# 定義一個限流區(qū)域 # $binary_remote_addr 使用二進制格式的客戶端IP地址作為鍵 # zone=mylimit:10m 創(chuàng)建一個名為'mylimit'的共享內(nèi)存區(qū)域,大小為10MB # rate=10r/s 每秒最多允許1個請求 limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; upstream myweb { server 192.168.226.21:80 weight=1 max_fails=1 fail_timeout=1; }
在server模塊里配置
server { listen 80; # 定義服務(wù)器監(jiān)聽的端口為 80,這是 HTTP 協(xié)議的默認(rèn)端口。 server_name localhost; # 設(shè)置服務(wù)器名稱為 localhost,這意味著它將響應(yīng)發(fā)送到 localhost 的請求。 location /{ # 定義對根路徑("/")的請求的處理規(guī)則。 root /usr/share/nginx/html; # 設(shè)置文檔根目錄,這是 Nginx 在響應(yīng)請求時查找文件的地方。 index index.html index.htm; # 設(shè)置當(dāng)請求是一個目錄時,默認(rèn)會返回的文件。在這里,如果訪問根目錄("/"),會首先嘗試返回 index.html 文件,如果沒有找到,再嘗試 index.htm。 limit_req zone=mylimit; # 為根路徑的請求應(yīng)用請求限制,使用名為 mylimit 的限流規(guī)則。 limit_req_dry_run off; # 設(shè)置為on以在日志中查看限制的影響,而不會實際限制流量 proxy_pass http://myweb; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
#修改默認(rèn)打開頁面,用來區(qū)分兩個主機 #修改192.168.226.20主機 echo "webserver1" > /usr/share/nginx/html/index.html #修改192.168.226.21主機 echo "webserver2" > /usr/share/nginx/html/index.html
#兩個主機都重啟nginx systemctl restart nginx
瀏覽器訪問192.168.226.20實際上會看到webserver2的字樣頁面,然后刷新看,有失敗和成功頁面,就完成了基本的限流設(shè)置。跑完go代碼看結(jié)果如果(比率是有一點波動的是正常的):
limit_req_zone
指令定義了流量限制相關(guān)的參數(shù),而limit_req
指令在出現(xiàn)的上下文中啟用流量限制(示例中,對于”/login/”的所有請求)。
limit_req_zone
指令通常在HTTP塊中定義,使其可在多個上下文中使用,它需要以下三個參數(shù):
Key - 定義應(yīng)用限制的請求特性。示例中的 Nginx 變量
$binary_remote_addr
,保存客戶端IP地址的二進制形式。這意味著,我們可以將每個不同的IP地址限制到,通過第三個參數(shù)設(shè)置的請求速率。(使用該變量是因為比字符串形式的客戶端IP地址$remote_addr
,占用更少的空間)Zone - 定義用于存儲每個IP地址狀態(tài)以及被限制請求URL訪問頻率的共享內(nèi)存區(qū)域。保存在內(nèi)存共享區(qū)域的信息,意味著可以在Nginx的worker進程之間共享。定義分為兩個部分:通過
zone=keyword
標(biāo)識區(qū)域的名字,以及冒號后面跟區(qū)域大小。16000個IP地址的狀態(tài)信息,大約需要1MB,所以示例中區(qū)域可以存儲160000個IP地址。Rate - 定義最大請求速率。在示例中,速率不能超過每秒10個請求。Nginx實際上以毫秒的粒度來跟蹤請求,所以速率限制相當(dāng)于每100毫秒1個請求。因為不允許”突發(fā)情況”(見下一章節(jié)),這意味著在前一個請求100毫秒內(nèi)到達的請求將被拒絕。
當(dāng)Nginx需要添加新條目時存儲空間不足,將會刪除舊條目。如果釋放的空間仍不夠容納新記錄,Nginx將會返回 503狀態(tài)碼(Service Temporarily Unavailable)。另外,為了防止內(nèi)存被耗盡,Nginx每次創(chuàng)建新條目時,最多刪除兩條60秒內(nèi)未使用的條目。
limit_req_zone
指令設(shè)置流量限制和共享內(nèi)存區(qū)域的參數(shù),但實際上并不限制請求速率。所以需要通過添加
limit_req
指令,將流量限制應(yīng)用在特定的location
或者server
塊。在上面示例中,我們對/login/
請求進行流量限制。
現(xiàn)在每個IP地址被限制為每秒只能請求10次/login/
,更準(zhǔn)確地說,在前一個請求的100毫秒內(nèi)不能請求該URL。
3、處理突發(fā)
如果我們在100毫秒內(nèi)接收到2個請求,怎么辦?對于第二個請求,Nginx將給客戶端返回狀態(tài)碼503。這可能并不是我們想要的結(jié)果,因為應(yīng)用本質(zhì)上趨向于突發(fā)性。相反地,我們希望緩沖任何超額的請求,然后及時地處理它們。我們更新下配置,在limit_req
中使用burst
參數(shù):
重啟nginx然后運行g(shù)o代碼請求測試
burst
參數(shù)定義了當(dāng)請求速率超過rate
參數(shù)所設(shè)定的限制時,允許額外處理的請求數(shù)量。這些額外的請求將被暫時放入一個隊列中等待處理,而不是立即返回錯誤。但是訪問量大的話后面的排隊時間就會太慢,并不是最優(yōu)的選擇。
burst
參數(shù)定義了超出zone指定速率的情況下(示例中的mylimit
區(qū)域,速率限制在每秒10個請求,或每100毫秒一個請求),客戶端還能發(fā)起多少請求。上一個請求100毫秒內(nèi)到達的請求將會被放入隊列,我們將隊列大小設(shè)置為20。
這意味著,如果從一個給定IP地址發(fā)送21個請求,Nginx會立即將第一個請求發(fā)送到上游服務(wù)器群,然后將余下20個請求放在隊列中。然后每100毫秒轉(zhuǎn)發(fā)一個排隊的請求,只有當(dāng)傳入請求使隊列中排隊的請求數(shù)超過20時,Nginx才會向客戶端返回503。
4、無延遲的排隊
配置burst
參數(shù)將會使通訊更流暢,但是可能會不太實用,因為該配置會使站點看起來很慢。在上面的示例中,隊列中的第20個包需要等待2秒才能被轉(zhuǎn)發(fā),此時返回給客戶端的響應(yīng)可能不再有用。要解決這個情況,可以在burst
參數(shù)后添加nodelay
參數(shù):
重啟nginx運行g(shù)o測試代碼
使用nodelay
參數(shù),Nginx仍將根據(jù)burst
參數(shù)分配隊列中的位置,并應(yīng)用已配置的速率限制,而不是清理隊列中等待轉(zhuǎn)發(fā)的請求。相反地,當(dāng)一個請求到達“太早”時,只要在隊列中能分配位置,Nginx將立即轉(zhuǎn)發(fā)這個請求。將隊列中的該位置標(biāo)記為”taken”(占據(jù)),并且不會被釋放以供另一個請求使用,直到一段時間后才會被釋放(在這個示例中是,100毫秒后)。
假設(shè)如前所述,隊列中有20個空位,從給定的IP地址發(fā)出的21個請求同時到達。Nginx會立即轉(zhuǎn)發(fā)這個21個請求,并且標(biāo)記隊列中占據(jù)的20個位置,然后每100毫秒釋放一個位置。如果是25個請求同時到達,Nginx將會立即轉(zhuǎn)發(fā)其中的21個請求,標(biāo)記隊列中占據(jù)的20個位置,并且返回503狀態(tài)碼來拒絕剩下的4個請求。
現(xiàn)在假設(shè),第一組請求被轉(zhuǎn)發(fā)后101毫秒,另20個請求同時到達。隊列中只會有一個位置被釋放,所以Nginx轉(zhuǎn)發(fā)一個請求并返回503狀態(tài)碼來拒絕其他19個請求。如果在20個新請求到達之前已經(jīng)過去了501毫秒,5個位置被釋放,所以Nginx立即轉(zhuǎn)發(fā)5個請求并拒絕另外15個。
效果相當(dāng)于每秒10個請求的“流量限制”。如果希望不限制兩個請求間允許間隔的情況下實施“流量限制”,nodelay
參數(shù)是很實用的。
注意: 對于大部分部署,我們建議使用burst
和nodelay
參數(shù)來配置limit_req
指令。
5、高級配置示例
通過將基本的“流量限制”與其他Nginx功能配合使用,我們可以實現(xiàn)更細(xì)粒度的流量限制。
1、白名單
下面這個例子需要將上面做過的刪除,然后重新配置
#排除上面實驗的干擾,重新安裝配置nginx yum remove -y nginx yum install -y nginx systemctl enable --now nginx
下面這個例子將展示,如何對任何不在白名單內(nèi)的請求強制執(zhí)行“流量限制”:
vim /etc/nginx/nginx.conf
將下面的http塊替換nginx配置文件的里的http塊代碼,其他不用動
#將下面的http塊替換nginx配置文件的里的http塊代碼,其他不用動 http { include /etc/nginx/mime.types; # 包括MIME類型定義,讓Nginx能根據(jù)文件擴展名設(shè)置正確的Content-Type頭。 default_type application/octet-stream; # 設(shè)置默認(rèn)的MIME類型,當(dāng)文件類型未定義時使用。 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 自定義日志格式。 access_log /var/log/nginx/access.log main; # 定義access日志的存儲位置和使用的格式。 # 以下部分定義了基于IP地址的訪問限制。 geo $limit { default 1; # 默認(rèn)情況下,所有IP地址的$limit值設(shè)為1。 10.0.0.0/24 0; # 對于這兩個子網(wǎng)中的IP地址,將$limit設(shè)為0。 192.168.0.0/24 0; } # 根據(jù)$limit的值,動態(tài)地設(shè)置$limit_key變量。 map $limit $limit_key { 0 ""; # 如果$limit為0,$limit_key為空。 1 $binary_remote_addr; # 如果$limit為1,$limit_key使用二進制格式的客戶端IP地址。 } # 定義請求限制區(qū)域req_zone,按$limit_key對請求進行分組,每個組最多每秒處理5個請求。 limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; server { # 定義一個服務(wù)器監(jiān)聽在80端口。 listen 80; # 監(jiān)聽80端口。 server_name localhost; # 服務(wù)器名稱設(shè)置為localhost。 location / { # 對于根路徑的請求。 limit_req zone=req_zone burst=10 nodelay; # 應(yīng)用請求限制,允許突發(fā)請求高達10個。 root /usr/share/nginx/html; # 網(wǎng)站根目錄。 index index.html index.hml; # 定義默認(rèn)首頁。 } } include /etc/nginx/conf.d/*.conf; # 導(dǎo)入/etc/nginx/conf.d/目錄下的所有.conf配置文件。 }
這個例子同時使用了geo
和map
指令。geo
塊將給在白名單中的IP地址對應(yīng)的$limit
變量分配一個值0,給其它不在白名單中的分配一個值1。然后我們使用一個映射將這些值轉(zhuǎn)為key,如下:
如果
$limit
變量的值是0,$limit_key
變量將被賦值為空字符串如果
$limit
變量的值是1,$limit_key
變量將被賦值為客戶端二進制形式的IP地址
兩個指令配合使用,白名單內(nèi)IP地址的$limit_key
變量被賦值為空字符串,不在白名單內(nèi)的被賦值為客戶端的IP地址。當(dāng)limit_req_zone
后的第一個參數(shù)是空字符串時,不會應(yīng)用“流量限制”,所以白名單內(nèi)的IP地址(10.0.0.0/24和192.168.0.0/24 網(wǎng)段內(nèi))不會被限制。其它所有IP地址都會被限制到每秒5個請求。
limit_req
指令將限制應(yīng)用到/的location塊,允許在配置的限制上最多超過10個數(shù)據(jù)包的突發(fā),并且不會延遲轉(zhuǎn)發(fā)。
2、location 包含多l(xiāng)imit_req指令
我們可以在一個location塊中配置多個limit_req
指令。符合給定請求的所有限制都被應(yīng)用時,意味著將采用最嚴(yán)格的那個限制。例如,多個指令都制定了延遲,將采用最長的那個延遲。同樣,請求受部分指令影響被拒絕,即使其他指令允許通過也無濟于事。
擴展前面將“流量限制”應(yīng)用到白名單內(nèi)IP地址的例子:
http { # ... limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s; server { # ... location / { limit_req zone=req_zone burst=10 nodelay; limit_req zone=req_zone_wl burst=20 nodelay; # ... } } } 白名單內(nèi)的IP地址不會匹配到第一個“流量限制”,而是會匹配到第二個`req_zone_wl`,并且被限制到每秒15個請求。 不在白名單內(nèi)的IP地址兩個限制能匹配到,所以應(yīng)用限制更強的那個:每秒5個請求。
因此理解了原理,修改上面的http塊里的代碼進行測試:
#將下面的http塊替換nginx配置文件的里的http塊代碼,其他不用動 http { include /etc/nginx/mime.types; # 包括MIME類型定義,讓Nginx能根據(jù)文件擴展名設(shè)置正確的Content-Type頭。 default_type application/octet-stream; # 設(shè)置默認(rèn)的MIME類型,當(dāng)文件類型未定義時使用。 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 自定義日志格式。 access_log /var/log/nginx/access.log main; # 定義access日志的存儲位置和使用的格式。 # 以下部分定義了基于IP地址的訪問限制。 geo $limit { default 1; 10.0.0.0/24 0; 192.168.0.0/24 0; } # 根據(jù)$limit的值,動態(tài)地設(shè)置$limit_key變量。 map $limit $limit_key { 0 ""; # 如果$limit為0,$limit_key為空。 1 $binary_remote_addr; # 如果$limit為1,$limit_key使用二進制格式的客戶端IP地址。 } # 定義請求限制區(qū)域req_zone,按$limit_key對請求進行分組,每個組最多每秒處理5個請求。 limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s; server { # 定義一個服務(wù)器監(jiān)聽在80端口。 listen 80; # 監(jiān)聽80端口。 server_name localhost; # 服務(wù)器名稱設(shè)置為localhost。 location / { # 對于根路徑的請求。 limit_req zone=req_zone burst=10 nodelay; limit_req zone=req_zone_wl burst=20 nodelay; root /usr/share/nginx/html; # 網(wǎng)站根目錄。 index index.html index.hml; # 定義默認(rèn)首頁。 } } include /etc/nginx/conf.d/*.conf; # 導(dǎo)入/etc/nginx/conf.d/目錄下的所有.conf配置文件。 }
重啟nginx測試:
接下來將白名單和黑名單調(diào)換
重啟nginx并測試
因此:白名單內(nèi)的IP地址不會匹配到第一個“流量限制”,而是會匹配到第二個req_zone_wl
,并且被限制到每秒15個請求。不在白名單內(nèi)的IP地址兩個限制能匹配到,所以應(yīng)用限制更強的那個:每秒5個請求是正確的。
6、配置流量控制相關(guān)功能
1、配置日志記錄
默認(rèn)情況下,Nginx會在日志中記錄由于流量限制而延遲或丟棄的請求,如下所示:
2024/06/20 20:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.226.20, server: nginx.com, request: "GET / HTTP/1.0", host: "nginx.com"
日志條目中包含的字段:
limiting requests - 表明日志條目記錄的是被“流量限制”請求
excess - 每毫秒超過對應(yīng)“流量限制”配置的請求數(shù)量
zone - 定義實施“流量限制”的區(qū)域
client - 發(fā)起請求的客戶端IP地址
server - 服務(wù)器IP地址或主機名
request - 客戶端發(fā)起的實際HTTP請求
host - HTTP報頭中host的值
Nginx 的 limit_req_log_level
指令用于定義當(dāng)請求速率超出 limit_req
指定的速率限制時,日志記錄的級別。這允許你對因超出請求速率限制而被延遲或拒絕的請求進行特定級別的日志記錄,從而能夠更靈活地處理這些日志信息,而不必改變?nèi)值腻e誤日志級別。
limit_req_log_level
指令支持的日志級別包括:
- info: 記錄基礎(chǔ)信息,這是默認(rèn)設(shè)置。
- notice: 記錄正常但重要的情況。
- warn: 記錄更嚴(yán)重的警告信息。
- error: 記錄錯誤信息,這個設(shè)置通常用于希望對超限請求進行更加突出顯示的場景。
默認(rèn)情況下,Nginx以error
級別來記錄被拒絕的請求,如上面示例中的[error]
所示(Ngin以較低級別記錄延時請求,一般是info
級別)。如要更改Nginx的日志記錄級別,需要使用limit_req_log_level
指令。這里,我將被拒絕請求的日志記錄級別設(shè)置為warn
:
limit_req_zone $binary_remote_addr zone=myzone:10m rate=1r/s; server { location / { limit_req zone=myzone burst=5 nodelay; limit_req_log_level warn; ... } }
在上面的例子中,limit_req_zone
指令定義了一個名為 myzone
的速率限制區(qū)域,限制速率為每秒1個請求。在 server
塊的 location
部分,通過 limit_req
應(yīng)用了這個速率限制,并且設(shè)置了 burst
參數(shù)為5,表示允許短時間內(nèi)超出速率限制的請求在不被立即拒絕的情況下排隊等待處理。更重要的是,通過 limit_req_log_level warn
指令,指定了當(dāng)請求被延遲或拒絕時,這些事件將以 warn
級別記錄在日志中。這意味著只有當(dāng)請求因為超出速率限制而被延遲或拒絕時,才會在日志中以警告級別記錄,從而使這類事件在日志文件中更加突出,便于管理員進行分析和監(jiān)控。
擴展日志記錄級別:
注意區(qū)別這兩個日志對應(yīng)的層級關(guān)系和定義
Nginx 的日志記錄級別用于控制日志中記錄信息的詳細(xì)程度。在 Nginx 中,你可以為錯誤日志(error_log
指令)設(shè)置不同的日志級別,這些級別從最低到最高包括:
debug: 提供最詳盡的日志信息,包括調(diào)試信息。這個級別記錄所有的詳細(xì)操作,對于開發(fā)或調(diào)試非常有用,但在生產(chǎn)環(huán)境中會生成大量日志信息。
info: 記錄基礎(chǔ)的信息性消息,除了
debug
級別的信息。notice: 記錄正常但重要的條件。默認(rèn)級別,標(biāo)準(zhǔn)的錯誤和重要信息都會被記錄。
warn: 記錄警告信息,例如使用了非標(biāo)準(zhǔn)的配置指令或者有潛在的錯誤。
error: 記錄處理請求時發(fā)生的錯誤,但不會阻止服務(wù)運行的錯誤信息。
crit: 記錄臨界條件錯誤,比如嚴(yán)重的硬件或軟件錯誤。
alert: 要求立即采取行動的情況,如系統(tǒng)運行環(huán)境出現(xiàn)了非常嚴(yán)重的問題。
emerg: 記錄緊急情況,如系統(tǒng)不可用的情況。
配置錯誤日志級別的語法如下:
error_log /path/to/your/error.log level;
這里,/path/to/your/error.log
是想要保存錯誤日志的文件路徑,level
是上面提到的日志級別之一。如果不指定級別,error
級別會被使用。
在配置日志時,選擇適當(dāng)?shù)娜罩炯墑e對于優(yōu)化性能和管理日志文件大小很重要。例如,在開發(fā)環(huán)境中,可能會使用 debug
級別以便獲取盡可能多的信息來調(diào)試應(yīng)用。然而,在生產(chǎn)環(huán)境中,可能會選擇 notice
或 warn
級別,來減少日志文件的大小并關(guān)注更重要的系統(tǒng)消息。
2、發(fā)送到客戶端的錯誤代碼
一般情況下,客戶端超過配置的流量限制時,Nginx響應(yīng)狀態(tài)碼為503(Service Temporarily Unavailable)。可以使用limit_req_status
指令來設(shè)置為其它狀態(tài)碼(例如下面的412狀態(tài)碼):
可選擇范圍大約在400-599之間,并盡量避免與已存在的狀態(tài)碼產(chǎn)生沖突,造成歧義。
續(xù)接上面的配置,只需要在server模塊中的location模塊中加入一個參數(shù)為
limit_req_status 412;
添加的位置如圖說式:
重啟nginx
systemctl restart nginx
測試查看:
這里是因為我的go代碼的bug顯示黃色,因為換了裝填嗎顯示成失敗對應(yīng)的紅色,但其實已經(jīng)從默認(rèn)的503狀態(tài)碼切換到指定的412狀態(tài)碼了。
7、nginx 流量控制總結(jié)
以上已經(jīng)涵蓋了Nginx和Nginx Plus提供的“流量限制”的很多功能,包括為HTTP請求的不同loation設(shè)置請求速率,給“流量限制”配置burst
和nodelay
參數(shù)。還涵蓋了針對客戶端IP地址的白名單和黑名單應(yīng)用不同“流量限制”的高級配置,闡述了如何去日志記錄被拒絕和延時的請求。
到此這篇關(guān)于Nginx流量控制實現(xiàn)的文章就介紹到這了,更多相關(guān)Nginx流量控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
nginx刷新頁面出現(xiàn)404解決方案(親測有效)
本文主要介紹了nginx刷新頁面出現(xiàn)404解決方案,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03nginx啟動、關(guān)閉及重啟等簡單命令小結(jié)
這篇文章主要介紹了使用命令行重啟Nginx的方法,包括修改配置文件后重啟以使更改生效,查看端口占用情況,以及如何關(guān)閉Nginx,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03基于Nginx禁止指定IP、國外IP訪問我的網(wǎng)站
這篇文章主要介紹了用Nginx禁止指定IP、國外IP訪問我的網(wǎng)站,想要實現(xiàn)這個功能方法有很多種,這里基于 Nginx 的 ngx_http_geoip2 模塊來禁止國外 IP 訪問網(wǎng)站,需要的朋友可以參考下2022-05-05