首页 > 解决方案 > Apache Camel 优雅关闭 Oracle AQ 上的长时间接收超时

问题描述

我希望 Apache Camel 在默认的 45 秒内执行正常关闭。45 秒后,我希望强制关机。

我通常希望默认的 45 秒超时工作,但不幸的是,当在 Oracle AQ 上使用具有长接收超时的 JMS 组件时,它似乎不起作用。

上下文文件片段

<bean id="aqjms" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="aqJmsConnectionFactory" />
    <property name="transacted" value="true" />
    <property name="transactionManager" ref="dbTransactionManager" />
</bean>

停止 Java 代码

private org.apache.camel.spring.Main main;

@Override
public String call() throws Exception {
    try {
        LOG.info("Received stop command so stopping the server.");
        stopApplication();
    } catch (Exception e) {
        throw new AnException("Error occurred while executing the STOP command", e);
    }
    return "DONE";
}

public void stopApplication() {
    try {
        main.stop();
    } catch (Exception e) {
        System.out.println("Error stopping camel");
    } finally {
        System.exit(0);
    }
}

@Override
public String execute(CommandInput commandInput) {
    // All tasks before graceful shut down goes here..
    ExecutorService executor = Executors.newSingleThreadExecutor();
    FutureTask<String> ft= new FutureTask<String>(this);
    executor.execute(ft);
    LOG.info(" Executed stop command asynchronously for JVM {}", commandInput.getProcessName());
    return "STOP";
}

现在,如果我将我的 Oracle AQ 路由设置为像这样的短接收超时

aqjms://AQSCHEMA.SOME_AQ?concurrentConsumers=30
jms://SOME_IBM_MQ?concurrentConsumers=20&receiveTimeout=3600000
...

我得到了一个快速的骆驼关机。

Tue May 11 10:15:37 EDT 2021    INFO    Executed stop command asynchronoulsy for JVM SOMETHING  ClassWrapper{className='some.class'}    Camel (camelContext) thread #6 - JmsConsumer[AN_IBM_MQ_TOPIC]
Tue May 11 10:15:37 EDT 2021    INFO    Received stop command so stopping the server.   ClassWrapper{className='some.class'}    pool-10638-thread-1
Tue May 11 10:15:37 EDT 2021    INFO    CamelContext: camelContext has been shutdown, triggering shutdown of the JVM.   ClassWrapper{className='org.apache.camel.main.MainLifecycleStrategy'}   pool-10638-thread-1
Tue May 11 10:15:37 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) is shutting down  ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-10638-thread-1
Tue May 11 10:15:37 EDT 2021    INFO    Starting to graceful shutdown 120 routes (timeout 45 seconds)   ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-10638-thread-1
Tue May 11 10:15:37 EDT 2021    INFO    Route: first_route shutdown complete, was consuming from: somewhere ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  Camel (camelContext) thread #3 - ShutdownTask
...
119 more routes shutdown
...
Tue May 11 10:15:38 EDT 2021    INFO    Graceful shutdown of 120 routes completed in 1s337ms    ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-10638-thread-1
Tue May 11 10:15:38 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) uptime 1d7h9m4s   ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-10638-thread-1
Tue May 11 10:15:38 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) is shutdown in 1s539ms    ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-10638-thread-1
Tue May 11 10:15:38 EDT 2021    INFO    CamelContext: camelContext has been shutdown, triggering shutdown of the JVM.   ClassWrapper{className='org.apache.camel.main.MainLifecycleStrategy'}   pool-10638-thread-1
Tue May 11 10:15:38 EDT 2021    INFO    Received hangup signal, stopping the main instance. ClassWrapper{className='org.apache.camel.main.DefaultMainShutdownStrategy'} Camel Thread #131 - CamelHangupInterceptor

现在,如果我将我的 Oracle AQ 路由设置为像这样有很长的 receiveTimeout

aqjms://AQSCHEMA.SOME_AQ?concurrentConsumers=30&receiveTimeout=3600000
jms://SOME_IBM_MQ?concurrentConsumers=20&receiveTimeout=3600000
...

我得到一个缓慢的骆驼关机。

Mon May 10 11:38:38 EDT 2021    INFO    Received stop command so stopping the server.   ClassWrapper{className='some.class'}    pool-183-thread-1
Mon May 10 11:38:38 EDT 2021    INFO    CamelContext: camelContext has been shutdown, triggering shutdown of the JVM.   ClassWrapper{className='org.apache.camel.main.MainLifecycleStrategy'}   pool-183-thread-1
Mon May 10 11:38:38 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) is shutting down  ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-183-thread-1
Mon May 10 11:38:38 EDT 2021    INFO    Starting to graceful shutdown 119 routes (timeout 45 seconds)   ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-183-thread-1
Mon May 10 11:38:38 EDT 2021    INFO    Route: first_route shutdown complete, was consuming from: somewhere ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  Camel (camelContext) thread #3 - ShutdownTask
...
a couple more routes shutdown
...
Mon May 10 11:39:23 EDT 2021    WARN    Timeout occurred during graceful shutdown. Forcing the routes to be shutdown now. Notice: some resources may still be running as graceful shutdown did not complete successfully.   ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-183-thread-1
Mon May 10 11:39:23 EDT 2021    WARN    Timeout occurred during graceful shutdown. Forcing the routes to be shutdown now. Notice: some resources may still be running as graceful shutdown did not complete successfully.   ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-183-thread-1
Mon May 10 11:39:23 EDT 2021    WARN    Setup of JMS message listener invoker failed for destination 'AN_ORACLE_AQ_CONSUMER_ROUTE' - trying to recover. Cause: JMS-257: receive(long timeout) of javax.jms.MessageConsumer took more time than the network timeout configured at the java.sql.Connection.; nested exception is java.sql.SQLRecoverableException: IO Error: Socket read interrupted  ClassWrapper{className='org.apache.camel.component.jms.DefaultJmsMessageListenerContainer'} Camel (camelContext) thread #120 - JmsConsumer[AN_ORACLE_AQ_CONSUMER_ROUTE]
Mon May 10 11:39:23 EDT 2021    WARN    Setup of JMS message listener invoker failed for destination 'AN_ORACLE_AQ_CONSUMER_ROUTE' - trying to recover. Cause: JMS-257: receive(long timeout) of javax.jms.MessageConsumer took more time than the network timeout configured at the java.sql.Connection.; nested exception is java.sql.SQLRecoverableException: IO Error: Socket read interrupted  ClassWrapper{className='org.apache.camel.component.jms.DefaultJmsMessageListenerContainer'} Camel (camelContext) thread #120 - JmsConsumer[AN_ORACLE_AQ_CONSUMER_ROUTE]
Mon May 10 11:39:23 EDT 2021    INFO    Route: another_route shutdown complete, was consuming from: another_route   ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  Camel (camelContext) thread #3 - ShutdownTask
...
about 63 more routes shutdown
...
Mon May 10 12:06:25 EDT 2021    INFO    Route: AN_ORACLE_AQ_CONSUMER shutdown complete, was consuming from: AN_ORACLE_AQ ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'} Camel (camelContext) thread #3 - ShutdownTask
...
more routes shutdown
...
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Shut down complete. ClassWrapper{className='org.springframework.data.jdbc.jms.listener.oracle.AdtMessageListenerContainer'} pool-183-thread-1
...
the remainder of the routes shutdown
...
Mon May 10 12:06:25 EDT 2021    INFO    Graceful shutdown of 119 routes completed in 27m47s ClassWrapper{className='org.apache.camel.impl.engine.DefaultShutdownStrategy'}  pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) uptime 9h0m7s ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Apache Camel 3.7.2 (camelContext) is shutdown in 27m47s ClassWrapper{className='org.apache.camel.impl.engine.AbstractCamelContext'} pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    CamelContext: camelContext has been shutdown, triggering shutdown of the JVM.   ClassWrapper{className='org.apache.camel.main.MainLifecycleStrategy'}   pool-183-thread-1
Mon May 10 12:06:25 EDT 2021    INFO    Received hangup signal, stopping the main instance. ClassWrapper{className='org.apache.camel.main.DefaultMainShutdownStrategy'} Camel Thread #135 - CamelHangupInterceptor

通过测试,我观察到关闭可能需要与 Oracle AQ 消费者路由的接收超时时间一样长。IBM MQ 的较长 receiveTimeout 不会导致延迟关闭。我想使用 receiveTimeout 来防止过度使用 Oracle 服务器 cpu。我还想在短时间内关闭我的应用程序。

标签: javaspringapache-camelibm-mqoracle-aq

解决方案


推荐阅读