spring rabbitmq java 应用程序正确关闭

spring rabbitmq java application correct shutdown

我有一个基于 spring 和 spring-rabbit 库的独立 java 应用程序。我这样开始:

nohup java -jar myapp.jar &

但有时我必须重新启动应用程序才能升级它。现在我使用 killall -9 java,但这不是最好的方法。如何正确地停止它并确保在那个时间段内所有发送给这个应用程序的兔子听众的请求都不会被部分处理,而只会被拒绝并转到其他兔子消费者?

首先,如果你害怕数据丢失,请不要使用autoack。设置 autoAck = false,然后在你的消费者中,当处理消息时,当你真正完成消息处理时,确认或 nack。因此,如果您以某种方式关闭 java 进程(即使您关闭了您的机器),您也不会丢失数据。 RabbitMq 将存储它直到您的客户端确认它。 阅读这里 https://www.rabbitmq.com/tutorials/tutorial-two-java.html 在 'message acknoledgement' 部分。 为了正确地 运行 您的 java 进程,编写您的 bash 脚本,这将 stop/start/restart 您的程序。

首先 - 不要使用 killall -9 - 它会向 JVM 发送一个 SIGKILL 信号,该信号无法被拦截并且不允许有序关闭。相反,使用 killallkillall -1515 是默认信号)来发送 SIGTERM,它被 JVM 拦截并允许有序关闭。

其次 - 不要过早地确认 RabbitMQ 消息 - 只有在消息实际被处理后才这样做。在您确认消息之前,RabbitMQ 会将其保持在 "unacked" 状态。如果消费者在没有确认的情况下死亡,消息将被放回队列中以供另一个消费者接收。

根据您使用的框架,您可能需要在您创建的 ApplicationContext 上注册一个 shutdown hook to close your application in a clean way. For example, if you are using standalone Spring, you should call ConfigurableApplicationContext#registerShutdownHook 以确保正确关闭所有 bean(包括 RabbitMQ 消费者)。