http请求报文挂起案例
程序员文章站
2024-02-08 18:18:40
...
问题描述
最近在生产上出现了多次java应用服务器挂死的情况。
问题分析
从堆栈中可以看到大量的线程挂在
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
通过查看代码,发现是通过HttpUrlConnection进行http请求的,并且有超时设置。如下所示:
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);
通常情况下,阻塞在socket的write是比较少见的,也没有api可以专门设置写超时。看业务,主要是通过http发送图片数据给平台G进行图像识别,图片数据基本上需要数十K到数百K,在这种情况下,是有可能出现这种情况的。
为了提高效率,socket有读写缓冲区,当socket调用write的时候,会先将数据写入本端的写缓冲区,然后由底层的tcp协议负责将数据传输到对端的读缓冲区,从而腾出写缓冲区。如果数据很大,写缓冲区不够写,就存在等待的情况,如果对端没有及时处理数据,那么这个wrtie可能就会阻塞很长一段时间。
不幸的是,java普通的socket并没有提供写超时的设置参数,所以在设计上应该谨慎考虑传输大批量数据。不过,好在可以考虑nio来处理,例如使用httpclient4.x的异步http调用,是可以避免这种write阻塞情况的,参数设置如下:
private RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(SOCKET_TIMEOUT) //可对应读写超时
.setConnectTimeout(CONNECTION_TIMEOUT)
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
.build();
转载于:https://my.oschina.net/bonyfish/blog/846552
上一篇: java中List的排序问题
下一篇: 2020哈工大软件构造实验Lab3