nginx?http?499錯誤碼詳解以及解決辦法
背景
499作為nginx自定義的狀態(tài)碼,不像400、401、500、502等常見的http狀態(tài)碼,很多不太常用nginx的人可能并不能清楚理解他的含義,本文將簡單介紹一下499狀態(tài)碼的含義,以及出現(xiàn)后的排查和處理思路,以及proxy_ignore_client_abort參數(shù)是否能有效。
499是什么
nginx 對499的定義是 client has closed connection。這個定義比較模糊,簡單來說就是nginx在完成響應之前客戶端斷開了連接。
499是如何產生的
根據(jù)上面的定義,499產生的核心原因是客戶端在nginx完成響應之前斷開了連接??梢圆惶珖乐?shù)母爬ň褪?strong>nginx完成的響應時間超過了客戶端的超時時間。
排查思路
上面對499產生原因的概括其實不太準確,實際上造成499的原因有很多,接下來我就介紹主要的排查思路,以及我平時比較常見的幾種情況。
nginx作為火了很多年的高性能web服務,有許多的應用場景,我選擇比較常見的反向代理服務場景來介紹一下
在上述架構下,客戶端發(fā)起一個請求大約要經歷下面這些階段
這只是一個比較簡單的流程,實際上會更復雜一些,比如中間可能還是一些網絡設備已經其他的基礎服組件。
499的觸發(fā)時機
由于499是nginx記錄的狀態(tài)碼,所以客戶端斷開連接的時機是要在nginx接收HTTP請求行,到nginx發(fā)送響應這個區(qū)間內,所以如果客戶端在DNS解析或者TCP建連之前就超時的話是不會觸發(fā)499的,畢竟請求都沒有到達nginx。如果nginx已經開始返回響應了,此時客戶端就斷開連接的話,不會記錄499,會以響應的狀態(tài)碼為準,比如200。
499的影響
上面說過,499代表客戶端超時斷開了連接,大部分情況下499代表請求失敗了,需要根據(jù)業(yè)務場景評估影響。比如如果客戶端有重試邏輯, 499之后重試成功,那么實際上可能不會有很大的影響。
499還有一個比較容易被忽視的影響,由于499代表客戶端斷開了連接,那么客戶端重試的時候意味著會重新建立tcp連接甚至重新tls握手,在一些高并發(fā)的場景下,大量的499導致的客戶端重試可能會對服務端造成一定的壓力,此時我們需要考慮在服務端做一些降級策略,減少499造成的重試壓力。
499的排查方向
我們之前提到過,499觸發(fā)的根本原因是nginx返回的響應時間超過了客戶端的超時時間,所以我們一般有下面幾個排查方向:
1. 后端響應時間是否過長
這里的后端是一個比較籠統(tǒng)的說法,實際的后端邏輯中可能還包含數(shù)據(jù)庫的訪問以及api的調用等,我們可以先通過查看nginx 499的訪問日志中的upstream_response_time 字段確認后端處理時間是否明顯增加,如果是的話可以再進一步定位異常的環(huán)節(jié)。
2. nginx處理時間是否過長
需要查看nginx服務器的負載,比如cpu idle,load,網卡流量,io等是否有明細的升高或不足, nginx一般作為統(tǒng)一的反向代理服務,會代理多個域名,可以通過分析nginx請求日志,查看499的是否具有普遍性,如果在不同的域名,不同的后端服務中均有大量出現(xiàn)。配合之前說的nginx負載問題再進一步深入定位。
3. 客戶端超時時間是否過短
這種情況需要看下nginx的499的request_time是否都比較短,且?guī)缀跸嗟?,需要去看客戶端代碼中的調用的超時時間是否設置的不合理。
對相應時間要求比較高的服務比較容易出現(xiàn)499,由于http協(xié)議的限制,客戶端想提前終止請求必須關閉連接,所以比較容易出現(xiàn)499。
4. 客戶端網絡質量是否太差
這種情況服務端很難確認,需要有客戶端的訪問日志或者使用一些撥測工具。
以上是一些比較簡單的定位思路,沒涉及到一些性能問題的排查方向,這個涉及到服務、網絡和操作系統(tǒng)等很多方向的內容,這里不展開詳談了。
此外網上還有個傳言是快速post的請求會導致觸發(fā)nginx 499 。但是這個說法我從未找到具體的代碼支持和復現(xiàn),并且nginx是以性能著稱的web服務,感覺不會有這種限制,個人傾向是以訛傳訛。
如何解決
通過上面的排查思路的介紹,我們其實可以發(fā)現(xiàn)產生499的原因有很多,核心解決思路就是增加客戶端的超時時間,加快后端的響應速度,提供一些邊緣加速服務優(yōu)化客戶端的訪問鏈路等等。但是499終究是一個客戶端行為,我們在服務端側是很難完全解決的,根據(jù)業(yè)務場景的不同,可以自行評估499的重要程度,一般的業(yè)務場景少量偶發(fā)的499不需要特別關注。
proxy_ignore_client_abort 有用嗎?
然后就是簡單聊一下 nginx的 proxy_ignore_client_abort 這個參數(shù)。nginx官方的解釋是:
Determines whether the connection with a proxied server should be closed when a client closes the connection without waiting for a response.proxy_ignore_client_abort:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort
nginx默認會在client關閉連接的時候,同時關閉nginx向上游服務(后端)的連接,這個參數(shù)開啟后,nginx將不會同步關閉后端服務連接,后端服務完成響應后,此次請求nginx也將不會記錄499狀態(tài)碼,而是記錄后端對應的響應狀態(tài)碼。
不知道從什么時候這個參數(shù)被傳為可以是“解決”499的方法,然后如果你閱讀了我上面寫的內容后,應該會明白,這個參數(shù)不是解決499而是忽略499。并且一般我是不建議開啟此參數(shù)的。主要有這幾個原因:
1. 修改了響應的狀態(tài)碼,掩蓋異常請求
開啟這個參數(shù)后nginx的請求日志便和客戶端的記錄不一致。比如如果客戶端已經超時,但是nignx這邊仍然記錄的一條200狀態(tài)碼的訪問日志,這種后續(xù)問題排查和定位的時候,可能會提高排查難度。并且掩蓋了499這一異常狀態(tài)碼,不利于及時發(fā)現(xiàn)異常。
2. ??????會浪費后端資源
客戶端發(fā)起了一些很重的請求超時后,可能會不斷重試,開啟此參數(shù)nginx則不會中斷之前向后端發(fā)起的請求,可能會導致加重對后端資源的使用。
所以proxy_ignore_client_abort并不是解決499的方法,大家一定要注意。
總結
499是由于nginx響應完成前客戶端就斷開了連接導致的,排查原因一般從客戶端網絡狀態(tài),超時時間以及服務端的響應時間來排查。常見的業(yè)務場景下,少量的499其實不需要過多的關注。
proxy_ignore_client_abort可以忽略499,但不是解決方法,不建議大家開啟。沒有證據(jù)能證明快速post導致nginx499,這個應該是謠傳。
到此這篇關于nginx http 499錯誤碼詳解以及解決辦法的文章就介紹到這了,更多相關nginx http 499錯誤內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Kubernetes之安裝nginx-controller作為統(tǒng)一網關方式
這篇文章主要介紹了Kubernetes之安裝nginx-controller作為統(tǒng)一網關方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07