通过运行RabbitMQ使用者安全结束java应用程序的最佳方法是什么
我们有一个独立的java应用程序在Debian机器上进行一些后台处理。它必须处理的作业通过RabbitMQ消息发送 当java应用程序需要升级时,我们需要停止它(杀死它)。但我们必须确保目前没有消费者在处理消息。根据您的经验,实现这一目标的最佳方式是什么 我们试图向消费者发送“关机”消息,但似乎无法关闭队列或通道?!它冻结了应用程序! 或者有没有另一种解决方案,例如我们可以自动关闭应用程序,而不必在linux中执行kill命令 谢谢分享你的经验通过运行RabbitMQ使用者安全结束java应用程序的最佳方法是什么,java,rabbitmq,Java,Rabbitmq,我们有一个独立的java应用程序在Debian机器上进行一些后台处理。它必须处理的作业通过RabbitMQ消息发送 当java应用程序需要升级时,我们需要停止它(杀死它)。但我们必须确保目前没有消费者在处理消息。根据您的经验,实现这一目标的最佳方式是什么 我们试图向消费者发送“关机”消息,但似乎无法关闭队列或通道?!它冻结了应用程序! 或者有没有另一种解决方案,例如我们可以自动关闭应用程序,而不必在linux中执行kill命令 谢谢分享你的经验 问候语RabbitMQ Java库不提供(AFAI
问候语RabbitMQ Java库不提供(AFAIK)任何会在某些消息仍在处理时自动推迟使用者进程关闭的功能。因此,你必须自己做这件事 如果您的应用程序可以容忍,请关闭它。此时未确认的任何消息都将保留在代理内的队列中,并在使用者返回时重新传递 如果您不能容忍这种情况,并且必须确保所有正在进行的消息处理完成,那么您需要遵循类似于中的建议,并在关机处理程序中执行以下操作:
consumers = new ArrayList<BasicConsumer>();
consumers.add(...)
// Cancel all consumers
for (BasicConsumer consumer : consumers) {
try {
consumer.getChannel().basicCancel(consumer.getConsumerTag());
} catch (Exception e) {
// report
}
}
// Wait for all consumers to be cancelled
Timeout timeout = ...;
while (!consumers.isEmpty() && !timeout.isElapsed()) {
// Remove cancelled consumers
for (Iterator<BasicConsumer> iterator = consumers.iterator(); iterator.hasNext();) {
if (iterator.next().isCancelled())
iterator.remove();
}
}
// Here we could force-close the remaining timed-out consumers if we
// used our own ExecutorService by shutting down all of its threads.
connection.close();
consumers=newarraylist();
消费者。添加(…)
停止顺序:
consumers = new ArrayList<BasicConsumer>();
consumers.add(...)
// Cancel all consumers
for (BasicConsumer consumer : consumers) {
try {
consumer.getChannel().basicCancel(consumer.getConsumerTag());
} catch (Exception e) {
// report
}
}
// Wait for all consumers to be cancelled
Timeout timeout = ...;
while (!consumers.isEmpty() && !timeout.isElapsed()) {
// Remove cancelled consumers
for (Iterator<BasicConsumer> iterator = consumers.iterator(); iterator.hasNext();) {
if (iterator.next().isCancelled())
iterator.remove();
}
}
// Here we could force-close the remaining timed-out consumers if we
// used our own ExecutorService by shutting down all of its threads.
connection.close();
//取消所有使用者
for(基本消费者:消费者){
试一试{
consumer.getChannel().basicCancel(consumer.getConsumerTag());
}捕获(例外e){
//报告
}
}
//等待所有消费者被取消
超时=。。。;
而(!consumers.isEmpty()&&!timeout.iseproved()){
//删除已取消的消费者
for(Iterator Iterator=consumers.Iterator();Iterator.hasNext();){
if(iterator.next().isCancelled())
iterator.remove();
}
}
//在这里,如果我们
//通过关闭所有线程来使用我们自己的ExecutorService。
connection.close();
相关RabbitMQ ML线程:您可以使用持久消息,在这种情况下,您可以随时杀死它,因为返回或发出的消息不会丢失。松散耦合/异步com是人们使用MQs的众多原因之一。@Shahzeb是的,我们使用持久消息,对于某些作业,我们可以简单地终止它,并在重新启动时重新处理消息。但是有一项特殊的工作是使用外部api做一些业务,它不能被中断,因为一旦在这个过程中,就不可能在同一个请求上重新运行它。我确实理解这个理论,但我们使用RabbitMQ的方式并不是专门创建多个线程。这一切都是通过创建多个频道来完成的。因此,我真的不明白如何实现这一点。但我会根据你的建议继续寻找。再次使用Thx。如果关闭关机处理程序中的所有通道(除了如上所述等待处理所有正在进行的消息),该怎么办?这难道不能让你优雅地关机吗?嗨,布莱恩。我确实找到了一个有效的解决办法。你的帖子对此很有帮助,但我还没有找到时间发布解决方案。我希望这周我能做到!