我想要正确地停止一个jms应用程序,我有以下代码,其中我从监听器调用shutdown方法:
public void initiateAppShutDown(int returnCode){
SpringApplication.exit(context, ()-> returnCode);
}
public void shudDownApplication(){
LOGGER.debug("Arret de l'application injecteur");
initiateAppShutDown(0);
}我正在通过监听程序的方法onMessageReceived()执行关闭操作,但出现以下警告,即消息似乎被监听程序拒绝:
Failed to shut down 1 bean with phase value 2147483647 within timeout of 30000: [org.springframework.jms.config.internalJmsListenerEndpointRegistry]以及以下内容:
DefaultMessageListenerContainer:由于监听器容器同时停止,拒绝接收到的消息:
更新
这是我的计数器声明
// we increment the counter. incrementer nombre de messages traités
final AtomicInteger counter = new AtomicInteger(0); incrementCounter()方法递增counter
public void incrementCounter() {
counter.getAndIncrement();
}
public int get() {
return counter.get();
}下面是调用shutdown时的方法:
private void checkNumberMessagesProcessed() {
if(this.get() == Integer.parseInt(nbrMaxMessages)){
LOGGER.debug("fin de traitement reprise backout avec nombre de messages traites: " + this.get());
//close listeners
//shutdown();
//close application
shudDownApplication();
}
}即使我达到了nbrMaxMessages=1000参数,我仍然会处理消息,并且应用程序会自动重新启动:这是日志:
2020-09-18 11:59:34,702 DEBUG --- [Backout-1-2] g.c.s.b.c.GdrBackoutListener : end process backout with number of treated messages : 1000
2020-09-18 11:59:34,704 DEBUG --- [Backout-1-9] g.c.s.b.c.GdrBackoutListener : inject message 49585321304740080b5f1487913fe5270000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,705 DEBUG --- [Backout-1-5] g.c.s.b.c.GdrBackoutListener : inject message 495853213045f0080b5f08647b4ab6760000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,705 DEBUG --- [Backout-1-3] g.c.s.b.c.GdrBackoutListener : inject message 49585321304740080b5f116d7b4de1960000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,705 DEBUG --- [Backout-1-4] g.c.s.b.c.GdrBackoutListener : inject message 49585321304750080b5f136b3193b7690000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,708 DEBUG --- [pool-7-thread-1] g.c.s.b.c.GdrBackoutListener : Shutdown application injecteur backout
2020-09-18 11:59:34,709 DEBUG --- [Backout-1-4] g.c.s.b.c.GdrBackoutListener : inject message 495853213045f0080b5f14f4120ec5b60000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,709 DEBUG --- [Backout-1-3] g.c.s.b.c.GdrBackoutListener : inject message 495853213045f0080b5f14003c676edb0000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,711 DEBUG --- [Backout-1-5] g.c.s.b.c.GdrBackoutListener : inject message 49585321304750080b5f1394ecc8bc480000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,711 DEBUG --- [Backout-1-2] g.c.s.b.c.GdrBackoutListener : inject message 495853213045f0080b5f15042af6ac7b0000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,712 DEBUG --- [Backout-1-8] g.c.s.b.c.GdrBackoutListener : inject message 495853213045b0080b5f150c84093cf60000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,712 DEBUG --- [ackout-1-10] g.c.s.b.c.GdrBackoutListener : inject message 495853213045b0080b5f0887a7225de50000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,714 DEBUG --- [Backout-1-3] g.c.s.b.c.GdrBackoutListener : inject message 49585321304730080b5f1649ac4348a70000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,714 DEBUG --- [Backout-1-4] g.c.s.b.c.GdrBackoutListener : inject message 49585321304730080b5f14fffe80e4a10000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,716 DEBUG --- [Backout-1-5] g.c.s.b.c.GdrBackoutListener : inject message 49585321304740080b5f146dee9feec60000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,716 DEBUG --- [Backout-1-2] g.c.s.b.c.GdrBackoutListener : inject message 495853213045b0080b5f158b80eac21f0000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,718 INFO --- [pool-7-thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@53dbe163: startup date [Fri Sep 18 11:59:32 CEST 2020]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7a5ceedd
2020-09-18 11:59:34,719 DEBUG --- [Backout-1-3] g.c.s.b.c.GdrBackoutListener : inject message 495853213045b0080b5f08b16224e18f0000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,720 DEBUG --- [Backout-1-4] g.c.s.b.c.GdrBackoutListener : inject message 495853213047e0080b5f16b62be157e60000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,721 DEBUG --- [Backout-1-5] g.c.s.b.c.GdrBackoutListener : inject message 49585321304730080b5f15dd2ce0d2df0000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,721 DEBUG --- [Backout-1-2] g.c.s.b.c.GdrBackoutListener : inject message 495853213047e0080b5f084d3a3b00260000000000000000 dans INTERNAL_QUEUE with number of messages to trate to 1000
2020-09-18 11:59:34,723 INFO --- [pool-7-thread-1] o.s.c.s.DefaultLifecycleProcessor : Stopping beans in phase 2147483647发布于 2020-09-18 10:44:53
您在同一线程中触发了一个shutdown调用,这就像死锁一样,您的onMessage方法等待shutdown,而JMS容器正在等待正在运行的任务终止,它最终会超时。
要解决此问题,您可以使用触发关机的异步执行器,如下所示。
@Component
public class MessageListener {
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
@JmsListener(...)
public void onShutdownMessage(Message message){
// increase delay further if observer any issue, it will trigger shutdown call in 1 seconds
executorService.schedule(() -> {shudDownApplication();}, 1, TimeUnit.SECONDS);
}
}发布于 2020-09-22 22:01:29
最后我解决了这个问题。
我对我的监听器有一个循环依赖。
我试图告诉侦听器在等待所有线程完成工作后自行停止。
这是不正确的,因为我创建了一个错误处理程序,然后从JmsListener抛出错误。并通过抛出shutDownManager类对关机进行管理。在shutDownManager中,我创建了一个停止springApplication的新线程。这种方法适用于线程并发上下文。代码如下:
@Component
public class AppContextManager implements ApplicationContextAware {
private static ApplicationContext _appCtx;
@Override
public void setApplicationContext(ApplicationContext ctx){
_appCtx = ctx;
}
public static ApplicationContext getAppContext(){
return _appCtx;
}
public static void exit(Integer exitCode) {
System.exit(SpringApplication.exit(_appCtx,() -> exitCode));
}
}在错误处理程序中,当你想关闭你的应用程序时,你会捕捉到Jmslistener抛出的异常,你可以调用这个方法
private void shutDown(){
//JmsListenerEndpointRegistry bean = context.getBean(JmsListenerEndpointRegistry.class);
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
//bean.stop();
appContext.exit(0);
});
}这允许您静默地shutDown您的侦听器和自定义踏步等待所有线程完成执行
https://stackoverflow.com/questions/63946879
复制相似问题