Java RabbitMQ:几乎没有消息保持未确认状态
我有一个从RabbitMQ读取数据并写入数据库的使用者。我使用的Consumer类是用户定义的,它实现了Callable 手动用户方法:Java RabbitMQ:几乎没有消息保持未确认状态,java,rabbitmq,Java,Rabbitmq,我有一个从RabbitMQ读取数据并写入数据库的使用者。我使用的Consumer类是用户定义的,它实现了Callable 手动用户方法: public static void consume(Queue queue, String consumerName, int threadCount, int prefetchCount) throws Exception { DbUtil.initializeConnectionPool(); Connection connection
public static void consume(Queue queue, String consumerName, int threadCount, int prefetchCount) throws Exception {
DbUtil.initializeConnectionPool();
Connection connection = RabbitMqUtils.getConnection();
Channel channel = connection.createChannel();
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicQos(threadCount * prefetchCount);
queue.initiateConsumer(channel, consumer);
System.out.println("MQ Server: " + connection.getAddress() + ":" + connection.getPort());
System.out.println("Queue: " + queue.name);
// Multi-threading code.
threadPool = Executors.newFixedThreadPool(threadCount);
Class c = Class.forName(consumerName);
while (true) {
Consumer consumerInstance = (Consumer) c.newInstance();
java.sql.Connection dbConnection = null;
QueueingConsumer.Delivery delivery = null;
try {
delivery = consumer.nextDelivery();
dbConnection = DbUtil.getConnectionFromPool();
consumerInstance.setConsumerDetails(new String(delivery.getBody()), dbConnection, channel, queue, delivery);
threadPool.submit(consumerInstance);
} catch (Exception e) {
if (delivery != null) {
Consumer.reQueueMessage(delivery, new String(delivery.getBody()), channel, queue, e);
}
if (dbConnection != null) {
dbConnection.close();
}
}
}
}
调用方法:
@Override
public Object call() throws Exception {
try {
doWork(this.message, this.dbConnection);
channel.basicAck(this.delivery.getEnvelope().getDeliveryTag(), false);
} catch (Exception e) {
Consumer.dumpMsg(e.getMessage(), "Error Msg");
Consumer.reQueueMessage(this.delivery, new String(this.delivery.getBody()), this.channel, this.queue, e);
} finally {
java.sql.Connection dbConnection = this.dbConnection;
if (dbConnection != null) {
dbConnection.close();
}
}
return null;
}
doWork是我的方法,它在Consumer类的子类中被重写。问题是大约1000条消息中有1条在未确认状态下卡在队列中。我只能通过停止然后启动消费者使其脱离未确认状态。我的猜测是确认信息在网络流量中丢失了。我想知道是否有办法使消息在返回队列之前仅保持未确认状态一段时间,以便重新使用。您是否在线程之间共享通道?这可能是问题的原因之一。关于你的另一个问题,不,对于挂起的消息没有超时ack@old_sound,是的,看起来我确实在共享一个频道。