我正在使用rabbitmq,我想确保如果我在客户端遇到连接问题,我发布的消息就不会丢失。我用eclipse模拟它:我做system.exit在100条消息之后获取程序。我发布了1000封邮件。第二次运行我没有限制消息的数量,它返回840条消息3次。你能帮助我吗?
制作人的代码是:
public void run() {
String json =SimpleQueueServiceSample.getFromList();
while (!(json.equals(""))){
json =SimpleQueueServiceSample.getFromList();
try {
c.basicPublish("", "test",
MessageProperties.PERSISTENT_TEXT_PLAIN, json.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
c.waitForConfirmsOrDie();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
安排的代码是:
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
System.out.println(count++);
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
答案 0 :(得分:0)
因此,您的方案面临的挑战是如何处理确认。
channel.basicConsume(QUEUE_NAME, true, consumer);
是问题所在。 true
的第二个参数是自动确认字段。
要解决此问题,请使用:
channel.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
//...
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
看起来您正在使用RabbitMQ的教程,而您的代码段来自part one。如果您查看part two,他们会开始讨论确认并设置服务质量以提供循环调度。
值得指出的是,basicConsume()
和nextDelivery()
组合依赖于消费者中隐藏的队列。因此,当您致电basicConsume()
时,会将几条消息下拉到客户端到本地存储。
这种方法的好处是可以避免因调用每条消息而产生额外的网络开销。问题是,它可以在本地消费者中放置超过您希望的消息,如果消费者在处理本地隐藏队列中的所有消息之前丢失消息,则可能会丢失消息。
如果您真的希望您的消费者一次只处理一条消息,以免丢失任何内容,您可能希望查看basicGet()
方法而不是basicConsume()
。