我有一个基于spring和spring-rabbit库的独立java应用程序。我这样开始:
nohup java -jar myapp.jar &
但有时我必须重新启动应用程序才能升级它。现在我使用killall -9 java,但它不是最好的方法。如何正确地停止它并确保在这段时间内来到这个应用程序的兔子听众的所有请求都不会被部分处理,只会被拒绝并转给其他兔子消费者?
答案 0 :(得分:1)
首先,如果您害怕数据丢失,请不要使用autoack。设置autoAck = false,然后在您的消费者中,当处理消息时,在您真正完成消息处理时确认或确认。因此,如果以某种方式关闭java进程(即使关闭计算机),也不会丢失数据。 RabbitMq将存储它,直到您的客户端确认它为止。 在这里阅读https://www.rabbitmq.com/tutorials/tutorial-two-java.html 在'消息acknoledgement'部分。 为了正确运行您的java进程,请编写您的bash脚本,它将停止/启动/重新启动您的程序。
答案 1 :(得分:1)
首先 - 不要使用killall -9
- 它向JVM发送SIGKILL
信号,该信号无法被截获,也不允许有序关闭。相反,使用killall
或killall -15
(15
是默认信号)发送SIGTERM
,它被JVM拦截并允许有序关闭。
其次 - 不要过早地确认RabbitMQ消息 - 只有在实际处理完消息后才这样做。在您确认消息之前,RabbitMQ会将其保持在“未经处理”状态。如果消费者在没有确认的情况下死亡,则该消息将被放回队列以供另一个消费者接收。
根据您使用的框架,您可能需要注册shutdown hook以便以干净的方式关闭您的应用程序。例如,如果您使用的是独立Spring,则应在您创建的ApplicationContext
上调用ConfigurableApplicationContext#registerShutdownHook
,以确保正确关闭所有bean(包括RabbitMQ使用者)。