情景再現
近期發現**訪問變慢,經常會出現請求無法響應的問題,乙個請求長時間沒有返回,導致頁面出現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請求超時問題排查
最近在專案中遇到乙個特殊情況,某個客戶通過https訪問公司的公網服務,有較大概率出現響應超時的問題。經過排查定位,確認以下資訊 1 客服伺服器訪問其他公司服務,均沒有出現大概率的超時問題。2 公司服務,壓力測試正常,且沒有其他客戶反饋此類問題。3 客戶公網出口,三大運營商各有一條。根據以上資訊,初...
記一次生產請求耗時的問題
最近發現lb上記錄的request time比upstream response time大的比較多,例如upstream response time記錄是0.062,request time記錄的就是5.064等等。整個耗時很反常。而且出現這個問題基本上都是乙個返回值比較大的介面,基本上返回值是1...
記一次 MySQL 的慢查優化
最近遇見乙個 mysql 的慢查問題,於是排查了下,這裡把相關的過程做個總結。我首先檢視了 mysql 的慢查詢日誌,發現有這樣一條 query 耗時非常長 大概在 1 秒多 而且掃瞄的行數很大 10 多萬條資料,差不多是全表了 select from tgdemand demand t1 wher...