黑人问号?!!定时任务出现异常过后停止执行

161 阅读1分钟

问题描述

项目在运行过程中,出现了定时任务异常过后停止执行的情况,日志如下

[2022-08-11 00:15:00,017][com.task.GetTask.getLatestDispatchList(GetTask.java:29)][INFO]开始执行获取最新派车单定时任务-------------------------->

[2022-08-11 00:21:05,657][com.task.GetTask.getLatestDispatchList(GetTask.java:37)][ERROR]获取最新派车单定时任务执行异常!

java.net.SocketTimeoutException: Read timed out

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.socketRead(Unknown Source)

at java.net.SocketInputStream.read(Unknown Source)

at java.net.SocketInputStream.read(Unknown Source)

at sun.security.ssl.InputRecord.readFully(Unknown Source)

at sun.security.ssl.InputRecord.read(Unknown Source)

at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)

at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)

at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)

at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)

at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)

at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)

at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)

at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)

at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)

at java.net.HttpURLConnection.getResponseCode(Unknown Source)

at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)

at com.service.impl.TmsServiceImpl.getOrigData(TmsServiceImpl.java:567)

at com.service.impl.TmsServiceImpl.getLatestDispatchList(TmsServiceImpl.java:103)

at com.service.impl.TmsServiceImpl$$FastClassBySpringCGLIB$$8bad373a.invoke()

at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)

at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)

at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)

at com.service.impl.TmsServiceImpl$$EnhancerBySpringCGLIB$$c4a1ede4.getLatestDispatchList()

at com.task.TmsTask.getLatestDispatchList(TmsTask.java:30)

at sun.reflect.GeneratedMethodAccessor49.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)

at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)

at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)

at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.util.concurrent.FutureTask.run(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

[2022-08-11 00:24:00,017][com.task.GetTask.getLatestDispatchList(GetTask.java:29)][INFO]开始执行获取最新派车单定时任务-------------------------->

原因分析

经排查,该定时任务使用了http请求但未设置连接超时和读超时时间,导致定时任务长时间未获取到数据时,相关的线程挂起等待了,以至于执行6分钟之后系统抛出SocketTimeoutException: Read timed out读超时,任务阻塞。

解决方案

在使用HttpsURLConnection时,设置连接超时和读超时时间,保证线程在超时过后不在继续执行,使得相关定时任务能够重新执行

HttpsURLConnection conn = null;
String sResult = "", sMethod = "GET";
URL url = new URL(url);
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod(sMethod);
// 设置连接超时时间, 值必须大于0,设置为0表示不超时 单位为“毫秒”
conn.setConnectTimeout(15*1000);
// 设置读超时时间, 值必须大于0,设置为0表示不超时 单位毫秒
conn.setReadTimeout(60*1000);
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.connect();