tft每日頭條

 > 生活

 > 前端頁面報錯

前端頁面報錯

生活 更新时间:2024-08-23 13:47:57

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)1

1.背景

本文主要是寫得最近比較影響深刻的一次排查客戶訪問業務前端域名,報504,timeout錯誤問題的記錄,該客戶為私有化部署,給客戶部署的服務存在跨洲調用,沒有專線,澳洲調用歐洲的服務情況,可能存在網絡延遲比較大,需要排查504的具體原因,然後通過優化參數臨時解決。

2.排查步驟和思路2.1 故障現象溝通

對于toB的客戶來說,通常在使用我們産品的時候,報錯隻會反饋一個截圖,我們需要向客戶溝通或者關鍵的信息,有利于問題排查。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)2

比如:

  • 打開的什麼頁面,便于自己複現
  • 具體報錯的接口是哪個?
  • 大概的報錯時間
  • 如果有x-request-id,拿到請求id
  • 具體報錯的url

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)3

2.2 梳理整個訪問請求的鍊路

我們需要了解,浏覽器上的請求鍊路,才能更好地去排查問題,比如我遇到的這個問題,請求鍊路是這樣的。

客戶機器訪問浏覽器域名 -> 私有端域名cdn(1) -> 私有端 SLB(2) -> 私有端 Nginx(3)-> saas端服務域名cdn (4) -> saas端 slb (5) -> saas 端nginx(6) -> saas端業務後端服務。

每個公司的業務情況不一樣,根據自己的實際情況梳理。

2.3 查看日志
  • 第一次問題排查

通過第一步故障現象的溝通,獲取的内容,然後去看鍊路上nginx(3),即私有端nginx的日志,想确認請求是否到達了服務器,根據 x-request-id搜索到日志,時間點和path也能對上,狀态碼是504,請求時間是30s,頁面多次刷新都是30s超時。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)4

于是檢查nginx上的配置,發現該接口location裡面的後端服務器響應時間,proxy_read_timeout時間設置為30s,相當于nginx會等待30s的時間來獲得請求的響應,如果在30s内如果響應接收不完,就會報出來504 timeout。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)5

于是,修改了将進行proxy_read_timeout時間修改為了300s,然後reload一下nginx。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)6

  • 第二次問題排查

客戶反饋訪問頁面依賴報錯504,timeout,于是繼續看nginx的日志,懷疑是不是沒生效,但是查看日志之後發現報錯狀态碼變了,是499,并且都是request_time為60s,其實就相當與客戶端的請求打到了Nginx上,Nginx把請求轉到後轉服務器A,由于nginx的proxy_connect_timeout 超時時間默認的60s,就會導緻Nginx把客戶端的請求轉到服務器A的時候,就會嘗試連接60s,而客戶端的響應時間設的是30s,所以造成客戶端造成大量超時情況,Nginx報大量的499。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)7

。然後經過查閱之後,發現需要增加參數proxy_ignore_client_abort修改為on,想看看真實情況,于是在報錯的location下增加了之後reload了nginx。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)8

繼續觀察日志,發現日志又變了,是報504 180s。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)9

此時開始懷疑是nginx之後的saas端nginx的的問題,然後根據 x-request-id搜索到日志,發現請求确實到了saas端,但是很明顯,日志打印出來的200,請求時長是60s。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)10

于是根據上面的鍊路情況,懷疑到了saas端和私有端的saas端slb (5) 上,經過客戶核實,他們用的阿裡雲的slb,默認的最大連接請求超時時間為180s,基本上和私有端的nginx裡面的日志大量出現180s超時能對應上。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)11

于是提供單給阿裡雲客服,咨詢是否可以調大,結論是不可以,監聽器http和https協議的最大隻能180s(其實人家是有道理的,這完全是由于我們私有端在澳洲,saas端在歐洲,跨洲訪問的結果),但是客服說可以采用tcp協議,能夠支持900s,于是新建了一個tcp協議的監聽器,連接超時時間也設置為350s(為了與nginx上的proxy_read_timeout區别開),然後把私有端的upstrem轉發的地址端口改成新的測試,客戶答複訪問正常。

  • 第三次問題排查

是我太天真了,以為完全解決了,但是第二天客戶反饋,随機性還是會出現504超時,期間讓客戶用浏覽器無痕模式打開,清理浏覽器緩存,依舊偶爾出現,影響客戶體驗,因此有了第三次問題排查。

依舊先去查看私有端nginx的日志,無異常,狀态碼都是200,隻是請求響應時間比較長超過60s了。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)12

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)13

查看saas端的nginx日志也是正常的。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)14

然後就不理解了,問題出在哪裡,然後讓客戶如果再次出現,就把報錯接口的copy url出來,然後手動在服務器請求url,能夠複現出來504,并且是nginx給返回的。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)15

于是在私有端一邊手動請求,一邊tcpdump抓包,發現也是正常的tcp三次握手連接,http正常請求返回,無異常。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)16

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)17

但是在請求返回的數據上,發現了一個端倪,server并不是nginx,我們的nginx因為修改過名字,叫Sws,所以剛才請求的時候nginx 504 timeout,不是我們業務側返回的,然後就懷疑到了請求鍊路上私有端 SLB(2) 上,于是找客戶确認,訪問的域名雖然走了cdn加速,但是會回源到這個slb上,然後監聽器的連接超時時間設置的的确是60s,然後客戶修改成180s,之後兩天沒有出現過超時的問題了。

3.排查過程中的知識點3.1 在nginx中 499狀态碼的定義和處理方法
  • 查看Nginx源碼

當客戶端主動關閉鍊接時,http狀态代碼中沒有可以表示該狀态的,但在nginx又需要記錄,所以自定義了一個499這個狀态來表示。

* * 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就記錄了499狀态,并且斷開了和後面服務端的連接(這樣可能導緻服務端返回數據時,因為連接斷開而報錯)。

前端頁面報錯(業務前端界面報錯504排查思路和解決辦法)18

  • 解決499問題
  • 查看服務端為什麼響應這麼慢,是否需要優化,或者調大客戶端的連接超時時間,不那麼快斷開
  • proxy_ignore_client_abort參數調整。

這個參數表示忽略客戶端終止情況,默認為off關閉狀态,當客戶端網絡中斷請求時,nginx 服務器中斷其對後端服務器的請求,并立即記錄 499 日志。

設置為 on 開啟,則nginx會忽略客戶端中斷,并一直等着代理服務執行返回,記錄後端返回的請求的狀态。

location =/api { proxy_ignore_client_abort on; proxy_pass http://service_backends; }

這個參數的意思是:在客戶端主動關閉連接後, nginx 與分發服務器的連接是否保持連接。如果參數設置了on,則客戶端如果斷開連接,nginx也不會斷開與後端服務端的連接,nginx會等待後端處理完(或者超時),然後記錄「後端的返回信息」到日志。所以,如果後端返回 200,就記錄 200 ;如果後端放回 5XX ,那麼就記錄 5XX 。如果超時(默認60s,可以用 proxy_read_timeout 設置),Nginx 會主動斷開連接,記錄 504。

注意:開啟後nginx隻會在讀取超時時關閉連接,默認為60s,可能出現請求連接擠壓的情況,所以默認情況下是關閉。如果開啟必須設置好proxy_read_timeout超時時間,并且nginx最好别做反向代理以外的事情。

這個方案隻是解決了兩個問題:(1)nginx上499的錯誤(2)服務端因為連接斷開報Broken pipe的錯誤。

所以最好的方法還是優化服務端。

3.2 nginx中的時間解釋

這個時間有沒有取決于nginx的日志格式log_format裡是否配置

  • request_time:指的就是從接收用戶請求的第一個字節到發送完響應數據的時間,即$request_time 包括接收客戶端請求數據的時間、後端程序響應的時間、發送響應數據給客戶端的時間。(request processing time in seconds with a milliseconds resolution; time elapsed between the first bytes were read from the client and the log write after the last bytes were sent to the client 。)
  • up_resp_time/upstream_response_time:指nginx從後端獲取結果的處理時間,從nginx和後端建立連接開始,到關閉連接為止,連接的後端地址為upstream_addr值。(keeps times of responses obtained from upstream servers; times are kept in seconds with a milliseconds resolution. Several response times are separated by commas and colons like addresses in the $upstream_addr variable)。
  • up_addr/upstream_addr:後端服務地址。
  • request_time時間肯定是要比up_resp_time要大的。
3.3 nginx中proxy相關的參數解釋

proxy_connect_timeout :後端服務器連接的超時時間_發起握手等候響應超時時間(代理連接超時)默認60s

proxy_read_timeout:它決定了nginx會等待多長時間來獲得請求的響應(代理接收超時)默認值60s

proxy_send_timeout :後端服務器數據回傳時間_就是在規定時間之内後端服務器必須傳完所有的數據(代理發送超時)默認值60s

4.總結
  • 當前修改配置參數實際上屬于非标準操作,本文隻是提供一個自己在排查過程的思路方向,每個問題的情況和背景不一樣,需要各自結合實際情況來調整。
  • 該問題主要還是跨洲訪問,沒有走專線,網絡這邊不穩定會導緻在請求的時候出現超時問題,然後根據具體的問題現在通過調整配置來臨時解決這個問題,讓客戶能正常使用,客戶是上帝。
  • 不要畏懼問題,所有的問題總能找到原因,不能一味地歸結到是網絡的問題,重啟大法來解決,我們其實可以定位得更清楚,需要知其然知其所以然。
,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved