服務器排障 之 nginx 499 錯誤的解決

問題描述:
Nginx 服務器大量499報錯

220.181.165.136 - - [18/May/2015:10:31:02 +0800] "POST /v1/jobsHTTP/1.1" 499 0 "" "bdHttpRequest/1.0.0"115.239.212.7 - - [18/May/2015:10:31:03 +0800] "GET /v1/job/643309e3-dc73-4025-aa69-c9405c1d818fHTTP/1.1" 499 0"http://www.baidu.com/?tn=91638679_hao_pg&s_j=1""Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko"140.207.202.187 - - [18/May/2015:10:30:58 +0800] "POST/v3/violations HTTP/1.1" 499 0 "-" "-"42.236.10.71 - - [18/May/2015:10:30:59 +0800] "POST /v3/violationsHTTP/1.1" 499 0 "-" "-"106.120.173.17 - - [18/May/2015:10:30:58 +0800] "POST/v3/violations HTTP/1.1" 499 0 "-" "Mozilla/5.0 (Windows NT6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131Safari/537.36"180.97.35.164 - - [18/May/2015:10:30:52 +0800] "GET/v1/job/f86bdecc-2a61-4a42-bb7b-aa794b77f89b HTTP/1.1" 499 0"http://www.baidu.com/s?word=%E5%8D%81%E5%A0%B0%E5%A4%A9%E6%B0%94&tn=sitehao123&ie=utf-8""Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"

問題分析:
1 499出現的原因
google定義:
499 / ClientClosed Request
An Nginx HTTP server extension. This codeis introduced to log the case when the connection is closed by client whileHTTP server is processing its request, making server unable to send the HTTP header back
維基百科定義:
499Client Closed Request (Nginx)
Used in Nginx logs to indicate when the connection has been closed by client while the server is still processing itsrequest, making server unable to send a status code back
Nginx源碼:
grep一下nginx源碼,定義在ngx_request_t.h :

/*
* HTTP does notdefine the code for the case when a client closed
* the connectionwhile we are processing its request so we introduce
* own code to logsuch situation when a client has closed the connection
* before we even tryto send the HTTP header to it
*/

#define NGX_HTTP_CLIENT_CLOSED_REQUEST 499
這是nginx定義的一個狀態碼,用于表示這樣的錯誤:服務器返回http頭之前,客戶端就提前關閉了http連接
繼續grep :
wKioL1ZK_oWDZn9NAAC_HrhuQAs422.png

這很有可能是因為服務器端處理的時間過長,客戶端“不耐煩”了。
要解決此問題,就需要在程序上面做些優化了。

再grep下“NGX_HTTP_CLIENT_CLOSED_REQUEST”,發現目前這個狀態值只在ngx_upstream中賦值

upstream在以下幾種情況下會返回499:

1)upstream 在收到讀寫事件處理之前時,會檢查連接是否可用:
ngx_http_upstream_check_broken_connection,if (c->error) { //connecttion錯誤……if (!u->cacheable) { //upstream的cacheable為false,這個值跟http_cache模塊的設置有關。指示內容是否緩存。ngx_http_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST);}
}

如上代碼,當連接錯誤時會返回499。
(2)server處理請求未結束,而client提前關閉了連接,此時也會返回499。
(3)在一個upstream出錯,執行next_upstream時也會判斷連接是否可用,不可用則返回499。
總之,這個錯誤的比例升高可能表明服務器upstream處理過慢,導致用戶提前關閉連接。而正常情況下有一個小比例是正常的。
繼續分析:
問題的核心就是要排查為什么服務端處理時間過長
可能問題:
1 后臺python程序處理請求時間過長
2 mysql慢查詢
通過查看監控:
1 cpu和內存的使用,都在正常范圍
2 后臺程序訪問正常
3 MySQL沒有慢查詢

結果:
經過詢問老大后得知,這個nginx為查詢違章的api,用戶提交查詢后, python就去數據庫或者交通局的網站查詢。這個查詢會有消耗一定的時間,所以,用戶會主動斷開連接
解決問題:
proxy_ignore_client_abort on; #讓代理服務端不要主動關閉客戶端的連接。

默認 proxy_ignore_client_abort 是關閉的,此時在請求過程中如果客戶端端主動關閉請求或者客戶端網絡斷掉,那么 Nginx 會記錄 499,同時 request_time 是「后端已經處理」的時間,而upstream_response_time 為“-“ (已驗證)。

如果使用了 proxy_ignore_client_abort on ;
那么客戶端主動斷掉連接之后,Nginx 會等待后端處理完(或者超時),然后記錄「后端的返回信息」到日志。所以,如果后端返回 200,就記錄 200 ;如果后端放回 5XX ,那么就記錄 5XX 。
如果超時(默認60s,可以用 proxy_read_timeout 設置),Nginx 會主動斷開連接,記錄 504
注:只在做反向代理的時候加入,作為其他服務器的時候,關閉為好,默認設置是關閉的!



? ? ? 本文轉自Tenderrain 51CTO博客,原文鏈接:http://blog.51cto.com/tenderrain/2045110,如需轉載請自行聯系原作者


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257078.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257078.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257078.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

二叉查找樹的先序遍歷,中序遍歷,后序遍歷

1、有一個二叉查找樹,存儲者字符A,B,C,D,E,F,G,H,下面哪個結果是后序樹遍歷結果 A. ADBCEGFH B. BCAGEHFD C. BCAEFDHG D. BDACEFHG 我的結題思路是將每個答案按照后序的遍歷方法把二叉樹存儲數據的結構還原,看是否滿足二叉樹的性質。 二叉樹的性…

學習筆記(13):Python網絡編程并發編程-解決粘包問題-終極版本

立即學習:https://edu.csdn.net/course/play/24458/296244?utm_sourceblogtoedu 粘包現象解決(終極版) 1.簡單版的問題所在 1)報頭信息不一定只是包含著命令執行結果的字節數長度,在文件傳輸的時候也可能包含文件名等&#xff0c…

C#多態

C#多態 多態性(C# 編程指南)轉自MSDN通過繼承,一個類可以用作多種類型:可以用作它自己的類型、任何基類型,或者在實現接口時用作任何接口類型。這稱為多態性。C# 中的每種類型都是多態的。類型可用作它們自己的類型或用…

Ubuntu 14.04.02 安裝openvswitch-2.3.1

Open vSwitch安裝 安裝好操作系統 # lsb_release -a LSB Version: core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:core-3.0-noarch:core-3.1-amd64:core-3.1-noarch:core-3.2-amd64:core-3.2-noarch:core-4.0-amd64:core-4.0-noarch:core-4.1-amd64:core-4.1-noarch:security…

struts-上傳

一、創建項目項目名稱:demoupload二、添加jar包commons-fileupload-1.2.2.jarcommons-io-2.0.1.jarcommons-lang3-3.1.jarfreemarker-2.3.19.jarjavassist-3.11.0.GA.jarognl-3.0.5.jarstruts2-core-2.3.4.1.jarxwork-core-2.3.4.1.jar三、在web.xml文件中配置過濾器…

將數組作為參數,調用該函數時候給的是數組地址還是整個數組

1、在實際的應用中,數組經常作為函數參數,將數組中的數據傳遞到另外一個函數中,一般來說,傳遞可以采用兩種方法: 1>、數組元素作為函數的實參時,用法跟普通變量作參數相同,將數組元素的值傳遞…

C#項目中常用到的設計模式

C#項目中常用到的設計模式 1. 引言 一個項目的通常都是從Demo開始,不斷為項目添加新的功能以及重構,也許剛開始的時候代碼顯得非常凌亂,毫無設計可言。但是隨著項目的迭代,往往需要將很多相同功能的代碼抽取出來,這也是…

學習筆記(14):Python網絡編程并發編程-文件傳輸功能實現

立即學習:https://edu.csdn.net/course/play/24458/296245?utm_sourceblogtoedu 1.課程目的: 實現客戶端輸入下載文件的命令,然后將命令發送給服務端,服務端再執行下載文件的命令,最后將執行下載文件命令后的結果返回給客戶端&a…

NFS精簡版配置方法

此實驗的前提是防火墻需關閉。 1.關閉iptables /etc/init.d/iptables stop /etc/init.d/iptables status 2.關閉selinux setenforce 0 getenforce Permissive ---出現這個單詞即代表selinux臨時關閉,如需永久關閉則需修改/etc/sysconfig/selinux配置文件 …

Serializable接口中serialVersionUID字段的作用

序列化運行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號在反序列化過程中用于驗證序列化對象的發送者和接收者是否為該對象加載了與序列化兼容的類。 如果接收者加載的該對象的類的 serialVersionUID 與對應的發送者的類的版本號不同&…

重新認知指針

1、把指針指向的變量的數據類型稱為指針的數據類型;而任何一個指針變量本身數據值的類型都是unsigned long int 2.、指針變量名前的符號“*”表示的是指向運算。 3、不要認為“ *p" 是指針變量,指針變量是p而不是*p 4、

分布式數據庫 HBase

原文地址:http://www.oschina.net/p/hbase/ HBase 概念 HBase – Hadoop Database,是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,利用HBase技術可在廉價PC Server上搭建起大規模結構化存儲集群。 HBase是Google Bigtable的開源實…

學習筆記(15):Python網絡編程并發編程-進程理論

立即學習:https://edu.csdn.net/course/play/24458/296423?utm_sourceblogtoedu 1.進程:正在運行的一個過程或者一個任務; 2.進程與程序的區別:程序是一堆代碼,程序運行起來就是進程了,一個程序運行兩次,算…

【翻譯】Designing Websites for iPhone X

讓網站適配 iphone X 英文原文地址:https://webkit.org/blog/7929/...本文原文地址:https://github.com/cnsnake11/... The section below about safe area insets was updated on Oct 31, 2017 to reflect changes in the iOS 11.2 beta. 以下關于safe …

指針作為函數參數引用數組的任意元素

void swap(int *a,int*b) {*a*a^*b;*b*a^*b;*a*a^*b; } swap(data[j],data[j1]); int data[10]{13,55,48,13,62,45,754,0,10};以上是我遇到的問題,我覺得調用這個swap函數是不能這樣直接把數組的某個元素直接丟給swap數據 在程序中參加數據處理的量不是指…

使用 Log4Net 記錄日志

第一步:下載Log4Net 下載地址:http://logging.apache.org/log4net/download_log4net.cgi 把下載的 log4net-1.2.11-bin-newkey解壓后,如下圖所示: 雙擊bin文件夾 雙擊net文件夾,選擇針對.NET FramerWork的不同版本 找…

Xcode常用快捷鍵

1. 文件CMD N: 新文件CMD SHIFT N: 新項目CMD O: 打開CMD S: 保存CMDOPtS:保存所有文件CMD SHIFT S: 另存為CMD W: 關閉窗口CMD Q :退出XcodeCMD SHIFT W: 關閉文件2. 編輯CMD [: 左縮進CMD ]: 右縮進CMDshiftF:項目中查找CMDG:查找下一個CMDshiftG:查…

學習筆記(16):Python網絡編程并發編程-開啟子進程的兩種方式

立即學習:https://edu.csdn.net/course/play/24458/296424?utm_sourceblogtoedu #方式一:使用python內置模塊multiprocessing下的process類 from multiprocessing import Process import time#定義進程函數 def task(name):print(%s is running!%name)t…

ElasticSearch的API python調用

os json datetime datetime django.http HttpResponse reelasticsearch Elasticsearches Elasticsearch([])res8 es.search({:{:{:{::}}}} ) statistic():():hit res8[][]:a (%hit %hit[])a re.split(a);arow a:id row[] row[]idHttpResponse(a)轉載于:https://blog.51cto…