1. 程式人生 > >服務器異常返回碼總結

服務器異常返回碼總結

關閉連接 結果 返回結果 ulimit close csdn 主動 read sof

Nginx返回碼 500(Internal Server Error 內部服務器錯誤)

服務器內部錯誤,也就是服務器遇到意外情況,而無法執行請求。發生錯誤,一般的幾種情況:

  • Web項目中出現異常,項目應用中有Bug
  • 訪問量大的時候,由於系統資源限制,而不能打開過多的文件句柄

定位思路:

1.查看access.log

[root@prod-nginx-01 ~]# cat /var/log/nginx/access.log | grep --color ‘HTTP/1.1" 500‘
183.131.0.1 - - [21/Apr/2018:17:40:11 +0800] "POST /checkupdate HTTP/1.1" 500 158 "-" "okhttp/3.6.0" "-" 10.016
2.判斷是否是too many open files
  • 打開/etc/security/limits.conf
  • 修改 limits.conf文件,加上下面兩句命令
  * soft nofile 65535    * hard nofile 65535
  • 打開/usr/local/nginx/conf/nginx.conf,在worker_processes的下面增加一行配置 worker_rlimit_nofile 65535;
  • 重新啟動nginx
#查看系統默認的最大文件句柄數,系統默認是1024
[root@prod-nginx-01 ~]# ulimit -n
655350
#查看當前進程打開了多少句柄數,第一列是打開的進程數,第二列是進程ID
[root@prod-nginx-01 ~]# lsof -n|awk ‘{print $2}‘|sort|uniq -c|sort -nr|more | head -5
   4010 2911
   3860 2912
   3774 2913
   3517 2910
    137 13209

  

Nginx返回碼 499(client has closed connection 客戶端主動關閉)

官方解釋:
ngx_string(ngx_http_error_495_page), /* 495, https certificate error*/
ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
ngx_string(ngx_http_error_497_page), /* 497, http to https */
ngx_string(ngx_http_error_404_page), /* 498, canceled */
ngx_null_string,                    /* 499, client has closed connection */

499,客戶端關閉連接,這個狀態碼並不是http協議中定義的status code,而是nginx自己定義的一個狀態碼。

  • 由於服務器處理請求較多,客戶端在有效時間內沒有得到答復,主動關閉了連接。
  • 有人說把時間設置長一些或者使用proxy_ignore_client_abort on(讓代理服務端不要主動關閉客戶端的連接)。
  • 但是這樣也有一定的風險,會拖垮服務器。發生這個錯誤,如果服務器CPU和內存不算太高,一般是數據庫和程序的問題,數據庫處理較慢或者程序線程較低。
  • 結合情況調整,比如讀寫分離或者程序線程數調高。

client發送請求後,如果在規定的時間內(假設超時時間為500ms)沒有拿到nginx給的響應,則認為這次請求超時,會主動結束,這個時候nginx的access_log就會打印499狀態碼。

其實這個時候,server端有可能還在處理請求,只不過client斷掉了連接,因此處理結果也無法返回給客戶端。

499如果比較多的話,可能會引起服務雪崩。比如說,client一直在發起請求,客戶端因為某些原因處理慢了,沒有在規定時間內返回數據,client認為請求失敗,中斷這次請求,然後再重新發起請求。

這樣不斷的重復,服務端的請求越來越多,機器負載變大,請求處理越來越慢,沒有辦法響應任何請求。

我試圖定位了一下我們幾個項目中的499出現概率,目前統計的幾個接口的出現頻率。

interface_1 十萬分之五
interface_2 萬分之一
interface_3 千分之一
interface_4 千分之一
interface_5 千分之一

相較之下,與運維探討得出目前的錯誤率還是可以接收的,可暫不處理。
另外為何0秒返回499 這個不是很好定位確認,網上也沒有合理的實踐經驗,如果要定位需要在較低的概率中抓到出錯的請求,具體分析。
結論:可先觀察一段時間,如果一直較低概率出現,可暫不處理。

Http返回碼 400(Bad Request 錯誤請求)

1、語義有誤,當前請求無法被服務器理解。除非進行修改,否則客戶端不應該重復提交這個請求。

2、請求參數有誤。

如將原本Post請求的json格式的body換成binary格式就會返回這個錯誤碼及下面的返回結果。

{
    "timestamp": 1524322831388,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
    "message": "Required request body is missing: public com.test.http.model.common.Object com.test.http.controller.TestController.forTest(Object,javax.servlet.http.HttpServletRequest)",
    "path": "/interface"
}

Http返回碼 405(Method Not Allowed 不被允許的請求方法)

請求行中指定的請求方法不能被用於請求相應的資源。

如原本Post的請求,你換成了Get的請求方式,就會返回這個錯誤碼及下面的返回結果。

{
    "timestamp": 1524322516567,
    "status": 405,
    "error": "Method Not Allowed",
    "exception": "org.springframework.web.HttpRequestMethodNotSupportedException",
    "message": "Request method ‘GET‘ not supported",
    "path": "/interface"
}

參考文章:

https://www.cnblogs.com/kevingrace/p/7205623.html https://blog.csdn.net/qq_35621350/article/details/71056970 https://www.linuxidc.com/Linux/2017-01/140055.htm

服務器異常返回碼總結