RabbitMQ:很少有消息未被确认

时间:2015-09-30 10:32:32

标签: java rabbitmq

我有一个从RabbitMQ读取并写入我的数据库的消费者。我使用的Consumer类是用户定义的,它实现了Callable。

手动消费者方法:

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条卡在unacked状态的队列中。我只能通过停止然后启动消费者来使它们脱离unacked状态。我的猜测是网络流量中的确认丢失了。我想知道是否有一种方法可以使消息在返回队列之前暂时保持在unacked状态,以便重新使用。

0 个答案:

没有答案