伺服器中的錯誤記錄類似於這種:
124.65.133.242 – – [27/oct/2014:14:30:51 0800] “-” 400 0 “-” “-”
124.65.133.242 – – [27/oct/2014:14:31:45 0800] “-” 400 0 “-” “-”
#124.65.133 [.24222422 – –”
#124.65.133 [. 27/oct/2014:14:31:45 0800] “-” 400 0 “-” “-”
踩點
經過分析nginx的log文件,發現都是在一次正常存取之後產生的數個400錯誤,每次有大概連續出現1-6個不等,也並不是每次客戶造訪都會產生400錯誤。 再觀察產生400錯誤的前一次訪問是很正常的,200狀態碼,正常的文件,正常的來路,正常的user-agent… 一切都很和諧,那400是腫麼來的呢? 透過仔細觀察發現,所有產生400錯誤的前一次訪問的user-agent都是google chrome瀏覽器留下的,也就是說400錯誤是由chrome瀏覽器產生的。但是經過本地抓包發現,chrome是沒有向伺服器發送異常請求或資料包的。 在抓包分析中發現,chrome在存取伺服器時發起的連線不只一個,一般有5到6個不等,而如果請求的資源不需要那麼多連線時,chrome就會關閉未用的連接,這項技術叫做pre-connection「預先連接」。 通常我們造訪一個網站時,第一個取得的是一個html主文件,而裡面連結了網頁所需的css、js、圖片等其他媒體資源文件,而一般資源檔案和主html文件是在一個網域下的,預先連接就是在取得html之前就建立很多的tcp連接,而不是等到取得到html檔案之後再去連接伺服器取得其他的文件, 因為連接伺服器是需要消耗一些時間的,所以這項技術可以很大程度地加快網頁的呈現速度。 如果網頁html連結的資源比較少,或是客戶端有緩存,不需要連線下載,那麼chrome瀏覽器發出的5-6個連線很可能只有1個是需要的,其他的都得關閉掉,這樣就產生了一個問題:連接了伺服器,而沒有發送任何請求。對於這種情況,nginx是當做400錯誤來處理的,但由於連接已經關閉,錯誤訊息不會發送到客戶端,這就產生了日誌檔案中記錄了錯誤,而抓包分析中什麼也看不到的現象。
測試
一句評論
其它原因
網路上很多人寫過相關的文章,大多的人的原因是因為header 的頭部大小超了,引起回應400 告訴是bad request.但其實還有一種可能,就是像埠測試工具,只是檢查埠是否是活的。像 lvs 之類什麼的,也會造成這種問題,然後日誌中會出現大量的 400 錯誤。 對於上述問題可以在nginx.conf中,將client_header_buffer_size和large_client_header_buffers都調大,可緩解此問題。 ###以上是Linux伺服器nginx存取日誌裡出現大量http 400錯誤怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!