情况描述:
三星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,是否真正的解决,还需要检验。
.
.
.