EJB 调度程序在重试计时器超时期间因错误而挂起

EJB Scheduler hung with Error during retrying timeout for timer

我正在使用 EJB 调度程序每分钟 运行 一个任务。任务是从几个服务器(基于文件的服务器)流式传输数据(日志数据),然后将该数据保存到 MySQL 数据库。

此设置工作正常,但在随机情况下,EJB 调度程序会停止处理请求。我查看了应用程序日志,所有错误都与 JBoss 容器有关。

这是我用于运行调度程序的代码:

@Singleton
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class MyApplicationBean {

    @Schedule(minute = "*/1", hour = "*", persistent = false)
    @AccessTimeout(3600000L)
    public void onTimerWakeup() throws SomeApplicationException {

        processSomeTask(); // this is the task to stream data from some server and persist in MySQL
    }
}

调度程序挂起时的应用程序日志:

01:47:38,912 ERROR [org.jboss.as.ejb3] (EJB default - 9) JBAS014122: Error during retrying timeout for timer: [id=a8842a34-90b9-4f5d-bf88-1564ccb3d8cc timedObjectId=myapplication-war-1.0.3-SNAPSHOT.myapplication-war-1.0.3-SNAPSHOT.MyApplicationBean auto-timer?:true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@a8f72f7 initialExpiration=Fri Dec 18 00:00:00 PST 2015 intervalDuration(in milli sec)=0 nextExpiration=Mon Dec 28 10:53:00 PST 2015 timerState=ACTIVE: javax.ejb.ConcurrentAccessTimeoutException: JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on org.jboss.invocation.InterceptorContext$Invocation@7b28012d - could not obtain lock within 3600000MILLISECONDS
    at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:100) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.tx.EjbBMTInterceptor.handleInvocation(EjbBMTInterceptor.java:104) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.ejb3.tx.BMTInterceptor.processInvocation(BMTInterceptor.java:56) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53) [jboss-as-ee-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.component.singleton.SingletonComponentInstanceAssociationInterceptor.processInvocation(SingletonComponentInstanceAssociationInterceptor.java:52) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory.processInvocation(ShutDownInterceptorFactory.java:64) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [jboss-as-ee-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) [jboss-as-ee-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.2.Final-redhat-1.jar:1.1.2.Final-redhat-1]
    at org.jboss.as.ejb3.timerservice.TimedObjectInvokerImpl.callTimeout(TimedObjectInvokerImpl.java:101) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.ejb3.timerservice.task.CalendarTimerTask.callTimeout(CalendarTimerTask.java:60) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.ejb3.timerservice.task.TimerTask.retryTimeout(TimerTask.java:184) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.ejb3.timerservice.task.TimerTask.run(TimerTask.java:140) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0-45]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0-45]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0-45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0-45]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0-45]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.1.Final-redhat-1.jar:2.1.1.Final-redhat-1]

从上面的异常来看,我的理解是,由于 EJB 调度程序无法在 3600000 毫秒内获得锁,线程将超时,这似乎是预期的行为。但我无法理解的是,为什么所有 EJB 线程都完全停止了?有人可以帮忙吗?

环境详情:

事实证明,EJB 线程在创建与我从中提取数据的 URL 的连接时停止。在我的代码中,我使用以下代码创建连接和获取数据:

InputStream in = new URL("someURL").openStream();

因为我是直接使用 URL.openStream() API 获取 Stream,所以我没有办法设置连接或读取超时,如果服务器没有响应连接,EJB 线程就会在这里停止或及时阅读请求。从 JDK 文档中,我无法在 URL.openStream() API 上找到特定的连接或读取超时值。可能有一个非常大的超时或根本没有超时,我不确定。

为了解决这个问题,我使用 URLConnection class 来设置连接和读取超时值。见以下代码:

URLConnection urlConnection = new Url("someURL").openConnection();
urlConnection.setConnectTimeout(2000);
urlConnection.setReadTimeout(5000);

BufferedInputStream bIn = new BufferedInputStream(urlConnection.getInputStream());

这里有一个相关的 post 关于 URL.openStream() API 的超时问题:https://community.oracle.com/thread/1759067?start=0&tstart=0