記一次pending請求問題查找過程


情景再現

近期發現網站訪問變慢,經常會出現請求無法響應的問題,一個請求長時間沒有返回,導致頁面出現504(Gateway Timeout),我們使用的nodejs+ngnix(反向代理)。

猜測原因

  服務器內存使用過高,導致服務器處理緩慢?

  並發請求過多導致請求緩慢?

...

定位問題

  查看服務器cpu和內存使用情況:發現服務器的cpu空閑率為95%左右,內存使用率在40%~60%。會不是內存使用過高導致的呢?我們重啟了nodejs服務,此時我們觀察到內存使用率有所減少在20%~40%左右,結果並沒有什么用,訪問依舊很慢。

  是不是請求數過多導致的呢?查看服務器日志,發現每分鍾的請求量級並沒有特別高,應該不是這個問題。

  因為我們使用了nginx反向代理,就像看看是不是nginx服務器的配置問題。經過抓包查看,發現部分請求的時間有幾十毫秒還有幾十秒的,當達到60秒的時候,服務器出現504錯誤。(proxy_connect_timeout,proxy_read_timeout,proxy_send_timeout,在nginx中,這些的默認配置是60s,所以一旦請求超過一分鍾沒有響應,服務器就直接返回504)再三檢查nginx配置,沒有發現能夠改變這個問題。

  查看nodejs服務,檢查是否我們代碼層的邏輯導致服務器沒有響應,觸發nginx的超時。經過對代碼的測試,發現我們有一個發布上線的邏輯比較耗時,大概時間為5到6秒鍾,這個過程需要依賴第三方的服務,所以處理時間長度過長,在用戶發送請求時,部分用戶需要經歷這個過程。此時,訪問其他頁面的時候,就會出現這種情況。我們的做法是,將發布上線的邏輯,只在編輯的時候使用。普通用戶訪問的時候,使用上線生成的線上文件。你們一定覺得這樣問題就可以解決了,其實這是一個導火索,與另外的一個問題同時導致了線上的pedding問題。

  上面這個問題解決之后,發現向上並沒有任何太大的改觀。同時發現還有一個請求,依賴其他的服務器,那就是數據庫請求。我們重新審查了一下什么原因導致數據庫查詢請求過慢。我們查看了我們所有的數據庫慢查詢,發現一個共性,這些慢查詢的表數據量都很大,同時我們並沒有對這些表建立索引,導致查詢很慢。經過簡單的本地測試:設置過索引的查詢,在一個幾十萬條數據的表中,查詢時間1ms以內;未設置索引的情況下,同一個查詢語句需要的時間是200ms左右,結果令人差異,竟然差距這么大。我們對線上的數據庫表根據查詢需求,設置了索引,結果得到了很大的改觀,訪問速度有了顯著的提高,基本上很快就有了響應。


  此時,線上的問題得到了初步的解決。

思考

  通過上面的探索我們發現,一般出現一個請求pedding或者是504的情況,是因為服務器處理的太慢,無法快速響應,如果服務器再不能並發處理的話,可能就會出現這種情況,所以我們需要優化我們服務端處理的速度。

  針對這種情況,優化我們線上的邏輯:

  優化建表邏輯:考慮主鍵、外鍵、索引等情況,優化數據庫請求

  優化服務端邏輯:優化發布上線邏輯,不過度依賴第三方服務,如果需要依賴的話,盡量采用子進程完成,不影響主進程的響應;與此同時,完成多服務器同步問題,不需要用戶在訪問時,再進行生成,導致請求阻塞。

  其他性能優化:資源靜態化,資源加載等等問題




參考資料:
https://nodejs.org/api/http.html#http_class_http_agent
http://melon.github.io/blog/2014/12/08/nodejs-agent-and-size-limit-of-get-method/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM