摘要:此次定位,頗為複雜,而且有時讓人沒有思路,因為同一個接口,換一個環境又好使了,又不敢去懷疑代碼;然而有問題的環境,換一個接口也好使了,又不得不懷疑代碼
本文分享自華為雲社區《一次網絡請求超時分析-雲社區-華為雲》,作者:xiewenci 。
問題現象發起http請求,後端服務接口/v5/iot/11c9c88e6fb26bead43b75514dc380eb/routing-rule/rules?limit=10&marker=ffffffffff&offset=0,一直等待,一分鐘後返回響應,且中文亂碼顯示
分析過程異常環境的流信息
正常環境的流信息
從圖中看出正常環境是,服務端發送響應完成之後,由客戶端正常返回ACK,然後由客戶端發起FIN斷鍊請求。而異常環境則是服務端發送響應完成之後,客戶端也回了ACK,但是沒有主動發起斷鍊請求,直到超過keep-alive時間之後,由服務端發起了斷鍊請求(因為超時主動斷鍊)。現象是客戶端一直在等服務端發送響應(可能沒有發送完),所以懷疑服務端有緩存之類,沒有及時将響應流發送出去,所以繼續查看代碼
3. 查看代碼,在返回客戶端的時候,沒有flush和close操作,代碼如下
然後以為找到問題原因所在了,就嘗試修改代碼,如下:
增加了flush操作和close操作(放在了try語快中),最後測試執行,還是跟最初的現象一緻,還是會等待1分鐘後才會返回響應。這時就有點納悶了,再重新仔細分析,其實從流中可以看出來,服務端的響應是立馬返回給了客戶端的,如下圖
既然給了響應,那為什麼客戶端為什麼還要繼續等待呢?這裡有注意到圖中有幾個問号,這其實是中文字符亂碼了,所以這裡又懷疑是不是編碼格式導緻客戶端收到的Content-Length長度和收到的響應的長度不一緻,也就是客戶端實際收到的響應的長度小于Content-Length的長度,然後一直等待下去,所以繼續修改代碼代碼
4. 修改代碼,指定編碼格式為UTF-8,代碼如下:
替換環境版本,測試執行,響應就立馬返回了,果然是這個編碼格式的鍋
原因回顧1. 編碼格式不一緻就會導緻響應流的實際長度不一緻?答案是一定的,編碼格式不一緻,實際長度就是會不一緻,測試結果如下:
2. 為什麼之前的沒有出現過這個問題?是什麼原因導緻編碼格式丢失的
查看後端服務jar包,發現spring版本已經升級到5.2.21.RELEASE,此版本中沒有指定默認編碼格式為UTF-8
所以需要後端服務去指定編碼格式,或者網關服務統一處理
總結與思考此次定位,頗為複雜,而且有時讓人沒有思路,因為同一個接口,換一個環境又好使了,又不敢去懷疑代碼;然而有問題的環境,換一個接口也好使了,又不得不懷疑代碼;還有就是在容器中去調用接口,也是一樣的問題,所以感覺又跟網絡沒啥關系。其實應該靜下心來去思考為什麼客戶端那裡一直等待,沒有主動發起斷鍊,這裡還是說明了對HTTP協議細節,不夠熟練掌握,才導緻中間走了一些誤區,需要去鞏固和加深對http協議的理解。
點擊下方,第一時間了解華為雲新鮮技術~
華為雲博客_大數據博客_AI博客_雲計算博客_開發者中心-華為雲
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!