情況描述:
三星J7 小米5等手機,電信4G wifi環境下發生。
使用org.apache.http.client.HttpClient? 請求http://serverapi.qa.xxxx.com/user?
設置超時的情況下會timeout(使用域名請求時會出現問題,使用ip請求正常)
不設置超時的情況會無限等待
調試發現HttpResponse? getStatusCode 會拿到HttpStatus.SC_OK(200)
HttpResponse response = client.execute(request);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
? ? ?reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
? ? StringBuilder sb = new StringBuilder();
? ? for (String s = reader.readLine(); s != null; s = reader.readLine()) {
? ? ? ? ?sb.append(s);
? ? }
? ? json = sb.toString();
}.
具體代碼如上圖,for循環中會一直等待 ,reader 一直不會讀取到內容。
(在mac上連接 該電信4G網絡wifi,使用瀏覽器請求)
HTTP/1.1 200 OK
Server:?Tengine
Content-Type:?application/vnd.android.package-archive
而Status顯示:
Received response header. Waiting for response body…
網頁也一直在loading ,非常奇怪的狀態。
1.與后臺同事確認,接口無誤,正常。
2.與運維同學溝通,確定此接口服務器有SLB負載均衡。
判斷原因為客戶端沒有收到SLB發出的第二個包(Chunk模式下的最后一個包),導致客戶端接收到的信息不完整,持續出來等到接收的狀態。
為何這個包客戶端沒有收到,原因有二:1.)某些運營商把這個包丟棄了 2.)SLB沒有發回這第二個包(根據目前情況,第一個原因可能性大一些)
目前有三個解決方案:
1.客戶端請求時,header頭里不要帶上gzip參數
2.負載均衡后端ECS在返回http響應時,帶上Content-Length頭,告知負載均衡響應中含有多少字節,以免負載均衡使用Chunk模式向客戶端返回數據。
3.更換tcp監聽
1.客戶端請求沒有帶gzip
2.改用4層協議,會立即返回空包,不會timeout
3.帶上Content-Length頭,問題解決。
因為涉及的接口過多,還需要做大量的灰度測試才能上線,所以此問題以現在的情況看起來是OK,是否真正的解決,還需要檢驗。
.
.
.