问题现象:
? ? ? ? 现象1.开启定时任务线程池,线程池貌似消失了,定时任务突然中断,既不执行也不报错
? ? ? ? 现象2:跟换定时任务实现方式,使用@Scheduled,同意的现象依然出现了,定时任务跑到一定频率突然不动
解决思路:
????????1.程序未抛出异常,某个时期却突然不在执行,怀疑线程阻塞了
????????2.查询jvm线程状态(jstack?java进程ID >threadDump.log)将dump日志下载分析,发现该线程期处于runnable?状态,其他任务一直waiting,可以看出应该是http请求导致的
"scheduling-1" #62 prio=5 os_prio=0 tid=0x00007f36a6fc2000 nid=0x813e runnable [0x00007f3651125000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:593)
at sun.security.ssl.InputRecord.read(InputRecord.java:532)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:990)
- locked <0x00000006a6bb48d8> (a java.lang.Object)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:948)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
- locked <0x00000006a6bb4f38> (a sun.security.ssl.AppInputStream)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.read(SessionInputBufferImpl.java:197)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:188)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000006a6cab1e0> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:227)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:308)
at com.coco.util.HttpUtil.sendPost(HttpUtil.java:40)
? ? ? ? 3.查询资料,httpclient有一个这样的坑,必须配置http超时时间,否则请求未响应,会导致read一直处于阻塞状态,会导致程序假死
? ? ? ? 4.配置httpclient超时时间,问题解决,代码如下
// 设置超时时间-务必设置,否则导致程序阻塞或线程假死
int MAX_SOKET_TIMEOUT = 10000;
int MAX_CONNECTION_TIMEOUT = 8000;
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(MAX_SOKET_TIMEOUT).setConnectTimeout(MAX_CONNECTION_TIMEOUT).build();
CloseableHttpClient clientExecutor = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
? ? ? ? 5.思考扩展,导致假死的状态不只这一种,有可能是io、有可能是死循环(递归死循环等)、有可能是互斥锁,等等,都可以通过分析thread?dump文件来得到线索
|