499錯誤是什麼?讓我們看看NGINX的源碼中的定義:
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對應的是 “client has closed connection”。這很有可能是因爲服務器端處理的時間過長,客戶端“不耐煩”了。
499:客戶端關閉連接
這個乍一看,是客戶端的鍋,是它先“動手”,關閉連接的。從標準的 RFC2616 協議中,是沒有 499 狀態碼,
是 nginx 自己定義的。
根據字面的意思,這種情況是客戶端主動斷開連接,或許是服務端在客戶端最大等待時間內,沒有返回結果,導致客戶端等不及。
這次我們在終端試試(在寫的時候,已用瀏覽器測試,奈何瀏覽器作爲客戶端,等待時間太長了,復現不了)。
在網站根目錄添加test.php:
<?php
sleep(10);
echo "hello world";
在終端執行如下命令後直接Ctrl+c停止請求,
curl https://example.com/test.php
從nginx的access.log日誌中可以發現狀態碼爲499:
39.101.223.212 - - [13/Apr/2020:10:39:14 +0800] "GET /test.php HTTP/1.1" 499 0 "-" "curl/7.29.0" "-" "39.101.223.212"127.0.0.1:9000 2.524 2.525 -
因爲客戶端主動斷開,在下游的 nginx 就會有一條 499 的日誌。在普通的 web 應用中很少見,但是
在微服務下,跨部門跨組之間的調用,都是 http 請求,如果下游的服務不夠穩定,這種狀態碼一般很多。
上游要保證,在連接等待的時候,必須有合理的超時時間,不能因爲下游服務掛掉了,而拖垮自己,導致
整個服務雪崩。