Nginx code 常用状态码学习小结
?
最近了解下Nginx的Code狀態(tài)碼,在此簡單總結(jié)下。一個http請求處理流程:
一個普通的http請求處理流程,如上圖所示:
A -> client端發(fā)起請求給nginx
B -> nginx處理后,將請求轉(zhuǎn)發(fā)到uwsgi,并等待結(jié)果
C -> uwsgi處理完請求后,返回數(shù)據(jù)給nginx
D -> nginx將處理結(jié)果返回給客戶端
每個階段都會有一個預(yù)設(shè)的超時時間,由于網(wǎng)絡(luò)、機器負(fù)載、代碼異常等等各種原因,如果某個階段沒有在預(yù)期的時間內(nèi)正常返回,就會導(dǎo)致這次請求異常,進而產(chǎn)生不同的狀態(tài)碼。
1)504 錯誤
504主要是針對B、C階段。一般nginx配置中會有:
Nginx 504 Gateway Time-out的含義是所請求的網(wǎng)關(guān)沒有請求到,簡單來說就是沒有請求到可以執(zhí)行的PHP-CGI。Nginx 504 Gateway Time-out則是與nginx.conf的設(shè)置有關(guān)。504 Gateway Time-out問題常見于使用nginx作為web server的服務(wù)器的網(wǎng)站。
一般看來, 這種情況可能是由于nginx默認(rèn)的fastcgi進程響應(yīng)的緩沖區(qū)太小造成的, 這將導(dǎo)致fastcgi進程被掛起, 如果你的fastcgi服務(wù)對這個掛起處理的不好, 那么最后就極有可能導(dǎo)致504 Gateway Time-out現(xiàn)在的網(wǎng)站, 尤其某些論壇有大量的回復(fù)和很多內(nèi)容的, 一個頁面甚至有幾百K默認(rèn)的fastcgi進程響應(yīng)的緩沖區(qū)是8K, 我們可以設(shè)置大點在nginx.conf里, 加入:
fastcgi_buffers 8 128k 這表示設(shè)置fastcgi緩沖區(qū)為8×128k,當(dāng)然如果您在進行某一項即時的操作, 可能需要nginx的超時參數(shù)調(diào)大點, 例如設(shè)置成60秒:send_timeout 60;只是調(diào)整了上面這兩個參數(shù), 結(jié)果可能就是沒有再顯示那個超時!解決辦法:調(diào)整nginx.conf的相關(guān)設(shè)置: fastcgi_connect_timeout 600; fastcgi_send_timeout 600; fastcgi_read_timeout 600; fastcgi_buffer_size 256k; fastcgi_buffers 16 256k; fastcgi_busy_buffers_size 512k; fastcgi_temp_file_write_size 512k;?2)502 錯誤
502主要針對B 、C階段。產(chǎn)生502的時候,對應(yīng)的error_log中的內(nèi)容會有好幾種:
access_log
[16/May/2016:16:39:49 +0800] 10.4.31.56 201605161639490100040310562612 2612221463387989972 10.6.19.81 127.0.0.1:88 "GET /articles/?source_type=0 HTTP/1.1" 503 **.***.com **.**.**.4, **.**.**.160 0.000 0.000 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" "uuid=\x22w:546d345b86ca443eb44bd9bb1120e821\x22; tt_webid=15660522398; lasttag=news_culture; sessionid=f172028cc8310ba7f503adb5957eb3ea; sid_tt=f172028cc8310ba7f503adb5957eb3ea; _ga=GA1.2.354066248.1463056713; _gat=1"error_log
2016/05/16 16:39:49 [error] 90693#0: *944980723 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 10.6.19.80, server: **.***.com, request: "GET /articles/ HTTP/1.1", upstream: "http://127.0.0.1:8500/**/**/articles/", host: "**.***.com", referrer: "http://**.***.com/new_article/"列一下常見的幾種502對應(yīng)的 error_log:
- recv() failed (104: Connection reset by peer) while reading response header from upstream
- upstream prematurely closed connection while reading response header from upstream
- connect() failed (111: Connection refused) while connecting to upstream
- ....
這些都代表,在nginx設(shè)置的超時時間內(nèi),上游uwsgi沒有給正確的響應(yīng)(但是是有響應(yīng)的,不然如果一直沒響應(yīng),就會變成504超時了),因此nginx這邊的狀態(tài)碼為502。
如上,access_log中出現(xiàn)503,為什么?
這個是因為nginx upstream的容災(zāi)機制。如果nginx有如下配置:
upstream app_backup {server 127.0.0.1:8500 max_fails=3 fail_timeout=5s;server 127.0.0.1:88 backup; }- max_fails=3 說明嘗試3次后,會認(rèn)為“ server 127.0.0.1:8500” 失效,于是進入 “server 127.0.0.1:88 backup”,即訪問本機的88端口;
- nginx upstream的容災(zāi)機制,默認(rèn)情況下,Nginx 默認(rèn)判斷失敗節(jié)點狀態(tài)以connect refuse和time out狀態(tài)為準(zhǔn),不過location里加了這個配置: proxy_next_upstream error http_502; proxy_connect_timeout 1s; proxy_send_timeout 6s; proxy_read_timeout 10s; proxy_set_header Host $host;
- 這個配置是說,對于http狀態(tài)是502的情況,也會走upstream的容災(zāi)機制;
- 概括一下就是,如果連續(xù)有3次(max_fails=3)狀態(tài)為502的請求,則會任務(wù)這個后端server 127.0.0.1:8500 掛掉了,在接下來的5s(fail_timeout=5s)內(nèi),就會訪問backup,即server 127.0.0.1:88 ,看下88端口對應(yīng)的是什么: server { listen 88;access_log /var/log/nginx/failover.log;expires 1m;error_page 500 502 503 504 /500.html;location / {return 503; }location = /500.html {root /**/**/**/nginx/5xx/;} }
這個的意思就是,對于訪問88端口的請求,nginx會返回503狀態(tài)碼,同時返回/opt/tiger/ss_conf/nginx/5xx/這個路徑下的500.html文件。
因此,access_log中看到的是503。
Nginx 502 Bad Gateway的含義是請求的PHP-CGI已經(jīng)執(zhí)行,但是由于某種原因(一般是讀取資源的問題)沒有執(zhí)行完畢而導(dǎo)致PHP-CGI進程終止。Nginx 502錯誤的原因比較多,一般就是因為在代理模式下后端服務(wù)器出現(xiàn)問題引起的。這些錯誤一般都不是nginx本身的問題,一定要從后端找原因!比如:php-cgi進程數(shù)不夠用、php執(zhí)行時間長、或者是php-cgi進程死掉,都會出現(xiàn)502錯誤。502錯誤最通常的出現(xiàn)情況就是后端主機宕機!!
一般來說Nginx 502 Bad Gateway和php-fpm.conf的設(shè)置有關(guān),php-fpm.conf有兩個至關(guān)重要的參數(shù),一個是"max_children",另一個是"request_terminate_timeout" ,但是這個值不是通用的,而是需要自己計算的。
計算的方式如下:
1)request_terminate_timeout
如果服務(wù)器性能足夠好,且寬帶資源足夠充足,PHP腳本沒有系循環(huán)或BUG的話你可以直接將"request_terminate_timeout"設(shè)置成0s。0s的含義是讓PHP-CGI一直執(zhí)行下去而沒有時間限制。而如果你做不到這一點,也就是說你的PHP-CGI可能出現(xiàn)某個BUG,或者你的寬帶不夠充足或者其他的原因?qū)е履愕腜HP-CGI能夠假死那么就建議你給"request_terminate_timeout"賦一個值,這個值可以根據(jù)你服務(wù)器的性能進行設(shè)定。一般來說性能越好你可以設(shè)置越高,20分鐘 -30分鐘都可以。由于我的服務(wù)器PHP腳本需要長時間運行,有的可能會超過10分鐘因此我設(shè)置了900秒,這樣不會導(dǎo)致PHP-CGI死掉而出現(xiàn)502 Bad gateway這個錯誤。
2)max_children
max_children這個值又是怎么計算出來的呢?這個值原則上是越大越好,php-cgi的進程多了就會處理的很快,排隊的請求就會很少。設(shè)置"max_children"也需要根據(jù)服務(wù)器的性能進行設(shè)定,一般來說一臺服務(wù)器正常情況下每一個php-cgi所耗費的內(nèi)存在20M左右,因此我的"max_children"我設(shè)置成40個,20M*40=800M也就是說在峰值的時候所有PHP-CGI所耗內(nèi)存在800M以內(nèi),低于我的有效內(nèi)存1Gb。而如果我的"max_children"設(shè)置的較小,比如5-10個,那么 php-cgi就會“很累",處理速度也很慢,等待的時間也較長。如果長時間沒有得到處理的請求就會出現(xiàn)504 Gateway Time-out這個錯誤,而正在處理的很累的那幾個php-cgi如果遇到了問題就會出現(xiàn)502 Bad gateway這個錯誤。
=================502的解決辦法================
一般解決辦法
臨時解決辦法
Nginx提示502和504錯誤的臨時解決辦法是:調(diào)整php-fpm.conf的相關(guān)設(shè)置: <value name=”max_children”>32</value> <value name=”request_terminate_timeout”>30s</value> fast-cgi的執(zhí)行腳本時間終級解決方案
以上解決方案只能臨時解決問題,而如果網(wǎng)站的訪問量確實非常非常大,而Nginx+FastCGI只能對處理瞬間或短時間內(nèi)的高并發(fā)有很好的效果, 所以目前唯一的終極解決方案是:定時平滑重啟php-cgi。1)寫一個非常簡單的腳本: # vim /home/www/scripts/php-fpm.sh #!/bin/bash # This script run at */1 /usr/local/php/sbin/php-fpm reload2)將腳本添加至計劃任務(wù):) # crontab -e */1 * * * * /home/www/scripts/php-fpm.sh為了省事起見,也可以不寫腳本,直接在crontab里寫入php-fpm的平滑重啟命令。Nginx 502錯誤情況
1))網(wǎng)站的訪問量大,而php-cgi的進程數(shù)偏少。 針對這種情況的502錯誤,只需增加php-cgi的進程數(shù)。具體就是修改/usr/local/php/etc/php-fpm.conf 文件,將其中的max_children值適當(dāng)增加。 這個數(shù)據(jù)要依據(jù)你的VPS或獨立服務(wù)器的配置進行設(shè)置。一般一個php-cgi進程占20M內(nèi)存,你可以自己計算下,適量增多。 /usr/local/php/sbin/php-fpm restart 然后重啟一下.2))CPU占用率、內(nèi)存占用率非常高,遭到CC攻擊. 解決方法請參考:Linux VPS簡單解決CC攻擊3)CPU占用率不高,內(nèi)存溢出。 檢查一下網(wǎng)站程序有沒有問題?一般小偷站點常常會出現(xiàn)內(nèi)存溢出。 檢查一下/var/log/目錄下的日志,看看是不是有人爆破SSH和FTP端口? SSH、FTP遭到窮舉也會占用大量內(nèi)存。是的話改掉SSH端口和FTP端口即可。3)499錯誤
client發(fā)送請求后,如果在規(guī)定的時間內(nèi)(假設(shè)超時時間為500ms)沒有拿到nginx給的響應(yīng),則認(rèn)為這次請求超時,會主動結(jié)束,這個時候nginx的access_log就會打印499狀態(tài)碼。
A+B+C+D > 500ms
其實這個時候,server端有可能還在處理請求,只不過client斷掉了連接,因此處理結(jié)果也無法返回給客戶端。
499如果比較多的話,可能會引起服務(wù)雪崩。
比如說,client一直在發(fā)起請求,客戶端因為某些原因處理慢了,沒有在規(guī)定時間內(nèi)返回數(shù)據(jù),client認(rèn)為請求失敗,中斷這次請求,然后再重新發(fā)起請求。這樣不斷的重復(fù),服務(wù)端的請求越來越多,機器負(fù)載變大,請求處理越來越慢,沒有辦法響應(yīng)任何請求
官網(wǎng)總結(jié)nginx返回499的情況,是由于:
client has closed connection #客戶端主動關(guān)閉了連接。client has closed connection ? ?#客戶端主動關(guān)閉了連接。
client has closed connection #客戶端主動關(guān)閉了連接。解決的話,可以添加
proxy_ignore_client_abort on;還有一種原因,確實是客戶端關(guān)閉了連接,或者連接超時。主要是因為PHP進程數(shù)太少,或php進程占用,資源不能很快釋放,請求堆積。這種情況要解決的話,需要在程序上做優(yōu)化。
499報錯即是客戶端關(guān)閉連接,這個狀態(tài)碼并不是http協(xié)議中定義的status code,而是nginx自己定義的一個狀態(tài)碼。由于服務(wù)器處理請求較多,客戶端在有效時間內(nèi)沒有得到答復(fù),主動關(guān)閉了連接。有人說把時間設(shè)置長一些或者使用proxy_ignore_client_abort on(讓代理服務(wù)端不要主動關(guān)閉客戶端的連接)。但是這樣也有一定的風(fēng)險,會拖垮服務(wù)器。發(fā)生這個錯誤,如果服務(wù)器CPU和內(nèi)存不算太高,一般是數(shù)據(jù)庫和程序的問題,數(shù)據(jù)庫處理較慢或者程序線程較低。結(jié)合情況調(diào)整,比如讀寫分離或者程序線程數(shù)調(diào)高。
4)500錯誤
服務(wù)器內(nèi)部錯誤,也就是服務(wù)器遇到意外情況,而無法執(zhí)行請求。發(fā)生錯誤,一般的幾種情況:
- web腳本錯誤,如php語法錯誤,lua語法錯誤等。
- 訪問量大的時候,由于系統(tǒng)資源限制,而不能打開過多的文件句柄
分析錯誤的原因
- 查看nginx,php的錯誤日志
- ?如果是too many open files,修改nginx的worker_rlimit_nofile參數(shù),使用ulimit查看系統(tǒng)打開文件限制,修改/etc/security/limits.conf
- 如果腳本存在問題,則需要修復(fù)腳本錯誤,并優(yōu)化代碼
- 各種優(yōu)化都做好,還是出現(xiàn)too many open files,那就需要考慮做負(fù)載均衡,把流量分散到不同服務(wù)器上去
5)503錯誤
503是服務(wù)不可用的返回狀態(tài)。
由于在nginx配置中,設(shè)置了limit_req的流量限制,導(dǎo)致許多請求返回503錯誤代碼,在限流的條件下,為提高用戶體驗,希望返回正常Code 200,且返回操作頻繁的信息:
6)400錯誤:request header or cookie too large
解決辦法: 修改nginx.conf,添加下面內(nèi)容(即增加緩沖區(qū)) [root@fvtlb01 ~]# vim /data/nginx/conf/nginx.conf ...... http { ...... client_header_buffer_size 8k; #默認(rèn)是4k(可以稍微改大,比如16K) large_client_header_buffers 4 8k;......}=================nginx日志"110: Connection timed out"報錯=================
訪問nginx頁面,出現(xiàn)5xx報錯。查看nginx日志,發(fā)現(xiàn)如下報錯信息: upstream timed out (110: Connection timed out) while reading response header from upstream解決辦法:修改fastcgi_read_timeout的時間值,默認(rèn)是60s,比如可以改成600s或3000s................................................Nginx Code Status...............................
200:服務(wù)器成功返回網(wǎng)頁 403:服務(wù)器拒絕請求。 404:請求的網(wǎng)頁不存在 499:客戶端主動斷開了連接。 500:服務(wù)器遇到錯誤,無法完成請求。 502:服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無效響應(yīng)。 503 - 服務(wù)不可用 504:服務(wù)器作為網(wǎng)關(guān)或代理,但是沒有及時從上游服務(wù)器收到請求。 這些狀態(tài)碼被分為五大類: 100-199 用于指定客戶端應(yīng)相應(yīng)的某些動作。 200-299 用于表示請求成功。 300-399 用于已經(jīng)移動的文件并且常被包含在定位頭信息中指定新的地址信息。 400-499 用于指出客戶端的錯誤。 (自己電腦這邊的問題) 自己電腦這邊的問題) 500-599 用于支持服務(wù)器錯誤。 (對方的問題) 對方的問題) --------------------------------------------------------------------------------------------- 200 (成功) 服務(wù)器已成功處理了請求。 通常,這表示服務(wù)器提供了請求的網(wǎng)頁。 201 (已創(chuàng)建) 請求成功并且服務(wù)器創(chuàng)建了新的資源。 202 (已接受) 服務(wù)器已接受請求,但尚未處理。 203 (非授權(quán)信息) 服務(wù)器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內(nèi)容) 服務(wù)器成功處理了請求,但沒有返回任何內(nèi)容。 205 (重置內(nèi)容) 服務(wù)器成功處理了請求,但沒有返回任何內(nèi)容。 206 (部分內(nèi)容) 服務(wù)器成功處理了部分 GET 請求。 --------------------------------------------------------------------------------------------- 300 (多種選擇) 針對請求,服務(wù)器可執(zhí)行多種操作。 服務(wù)器可根據(jù)請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網(wǎng)頁已永久移動到新位置。 服務(wù)器返回此響應(yīng)(對 GET 或 HEAD 請求的響應(yīng))時,會自動將請求者轉(zhuǎn)到新位置。 302 (臨時移動) 服務(wù)器目前從不同位置的網(wǎng)頁響應(yīng)請求,但請求者應(yīng)繼續(xù)使用原有位置來進行以后的請求。 303 (查看其他位置) 請求者應(yīng)當(dāng)對不同的位置使用單獨的 GET 請求來檢索響應(yīng)時,服務(wù)器返回此代碼。 304 (未修改) 自從上次請求后,請求的網(wǎng)頁未修改過。 服務(wù)器返回此響應(yīng)時,不會返回網(wǎng)頁內(nèi)容。 305 (使用代理) 請求者只能使用代理訪問請求的網(wǎng)頁。 如果服務(wù)器返回此響應(yīng),還表示請求者應(yīng)使用代理。 307 (臨時重定向) 服務(wù)器目前從不同位置的網(wǎng)頁響應(yīng)請求,但請求者應(yīng)繼續(xù)使用原有位置來進行以后的請求。 --------------------------------------------------------------------------------------------- 400 (錯誤請求) 服務(wù)器不理解請求的語法。 401 (未授權(quán)) 請求要求身份驗證。 對于需要登錄的網(wǎng)頁,服務(wù)器可能返回此響應(yīng)。 403 (禁止) 服務(wù)器拒絕請求。 404 (未找到) 服務(wù)器找不到請求的網(wǎng)頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內(nèi)容特性響應(yīng)請求的網(wǎng)頁。 407 (需要代理授權(quán)) 此狀態(tài)代碼與 401(未授權(quán))類似,但指定請求者應(yīng)當(dāng)授權(quán)使用代理。 408 (請求超時) 服務(wù)器等候請求時發(fā)生超時。 409 (沖突) 服務(wù)器在完成請求時發(fā)生沖突。 服務(wù)器必須在響應(yīng)中包含有關(guān)沖突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務(wù)器就會返回此響應(yīng)。 411 (需要有效長度) 服務(wù)器不接受不含有效內(nèi)容長度標(biāo)頭字段的請求。 412 (未滿足前提條件) 服務(wù)器未滿足請求者在請求中設(shè)置的其中一個前提條件。 413 (請求實體過大) 服務(wù)器無法處理請求,因為請求實體過大,超出服務(wù)器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網(wǎng)址)過長,服務(wù)器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求范圍不符合要求) 如果頁面無法提供請求的范圍,則服務(wù)器會返回此狀態(tài)代碼。 417 (未滿足期望值) 服務(wù)器未滿足"期望"請求標(biāo)頭字段的要求。 --------------------------------------------------------------------------------------------- 500 (服務(wù)器內(nèi)部錯誤) 服務(wù)器遇到錯誤,無法完成請求。 501 (尚未實施) 服務(wù)器不具備完成請求的功能。 例如,服務(wù)器無法識別請求方法時可能會返回此代碼。 502 (錯誤網(wǎng)關(guān)) 服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無效響應(yīng)。 503 (服務(wù)不可用) 服務(wù)器目前無法使用(由于超載或停機維護)。 通常,這只是暫時狀態(tài)。 504 (網(wǎng)關(guān)超時) 服務(wù)器作為網(wǎng)關(guān)或代理,但是沒有及時從上游服務(wù)器收到請求。 505 (HTTP 版本不受支持) 服務(wù)器不支持請求中所用的 HTTP 協(xié)議版本。proxy_intercept_errors
當(dāng)上游服務(wù)器響應(yīng)頭回來后,可以根據(jù)響應(yīng)狀態(tài)碼的值進行攔截錯誤處理,與error_page 指令相互結(jié)合。用在訪問上游服務(wù)器出現(xiàn)錯誤的情況下。
如下的一個配置實例:
[root@dev ~]# cat ssl-zp.wangshibo.conf upstream mianshi1 { server 192.168.1.33:8080 max_fails=3 fail_timeout=10s; #server 192.168.1.32:8080 max_fails=3 fail_timeout=10s; }server { listen 443; server_name zp.wangshibo.com; ssl on;### SSL log files ### access_log logs/zrx_access.log; error_log logs/zrx_error.log;### SSL cert files ### ssl_certificate ssl/wangshibo.cer; ssl_certificate_key ssl/wangshibo.key; ssl_session_timeout 5m;error_page 404 301 https://zp.wangshibo.com/zrx-web/;location /zrx-web/ { proxy_pass http://mianshi1; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto https; #proxy_set_header X-Forwarded-Proto https; proxy_redirect off; proxy_intercept_errors on; } }轉(zhuǎn)載于:https://www.cnblogs.com/kevingrace/p/7205623.html
總結(jié)
以上是生活随笔為你收集整理的Nginx code 常用状态码学习小结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【leetcode】Word Break
- 下一篇: 高仿微信实现左滑显示删除button功能