首页 文章

ActiveMQ:死信队列保持我的消息顺序

提问于
浏览
6

我使用ActiveMQ作为代理来传递消息 . 这些消息是用dabatase写的 . 有时,数据库无法访问或关闭 . 在这种情况下,我想回滚我的消息,以便稍后重试此消息,我想继续阅读其他消息 .

这段代码工作正常,除了一点:回滚消息阻止我阅读其他代码:

private Connection getConnection() throws JMSException {
    RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
    redeliveryPolicy.setMaximumRedeliveries(3); // will retry 3 times to dequeue rollbacked messages
    redeliveryPolicy.setInitialRedeliveryDelay(5 *1000);  // will wait 5s to read that message

    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
    Connection connection = connectionFactory.createConnection();
    ((ActiveMQConnection)connection).setUseAsyncSend(true);
    ((ActiveMQConnection)connection).setDispatchAsync(true);
    ((ActiveMQConnection)connection).setRedeliveryPolicy(redeliveryPolicy);
    ((ActiveMQConnection)connection).setStatsEnabled(true);
    connection.setClientID("myClientID");
    return connection;
}

我以这种方式创建会话:

session = connection.createSession(true, Session.SESSION_TRANSACTED);

回滚很容易问:

session.rollback();

假设我的队列中有3条消息:

1: ok
2: KO (will need to be treated again : the message I want to rollback)
3: ok
4: ok

我的消费者会做(线性序列):

commit 1 
rollback 2
wait 5s
rollback 2
wait 5s
rollback 2
put 2 in dead letter queue (ActiveMQ.DLQ)
commit 3
commit 4

但我想要 :

commit 1
rollback 2
commit 3
commit 4
wait 5s
rollback 2
wait 5s
rollback 2
wait 5s
put 2 in dead letter queue (ActiveMQ.DLQ)

那么,如何配置我的消费者以便以后延迟我的回滚消息呢?

3 回答

  • 0

    这实际上是预期的行为,因为消息重试由客户端而不是代理处理 . 因此,由于您有1个会话绑定,并且在DLQ之前为3次重试设置了重试策略,因此整个重试过程会阻止该特定线程 .

    所以,我的第一个问题是,如果数据库插入失败,您是否会因为类似的原因而不希望所有其他数据库插入失败?

    如果没有,那么解决这个问题的方法是将该队列的重试策略设置为0次重试,具有特定的DLQ,以便消息立即失败并进入DLQ . 然后有另一个进程每隔5秒从DLQ中取出并重新处理和/或将其放回主队列进行处理 .

  • 0

    您在ActiveMQ XML配置文件中使用<strictOrderDispatchPolicy />吗?我不确定这是否会影响重新发送的消息顺序 . 如果您使用严格的订单分派,请尝试注释该策略以查看是否更改了该行为 .

    布鲁斯

  • 8

    我有同样的问题,我没有在这里找到解决方案,所以决定在我找到一个为人们挣扎的同时发布它 . 在连接工厂中将属性nonBlockingRedelivery设置为true时,在5.6版之前修复了此问题:

    <property name="nonBlockingRedelivery" value="true" />
    

相关问题