【问题标题】:Artemis ActiveMQ + MDB long time work: how long it wait before redeliveryArtemis ActiveMQ + MDB 长时间工作:重新交付前等待多长时间
【发布时间】:2021-03-02 22:42:21
【问题描述】:

我有 Wildfly 21.0.0,配置了 jms-queue 和几个 in-vm 连接器/接受器。 然后我有一个消息驱动 Bean (MDB),它最多有 5 个并发会话,而不是处理收到的消息并做一些脏活。 在某些情况下,工作需要超过 5 分钟,并且队列将消息重新传递到 MDB,从而导致混乱。

我了解重新传递的概念,重新传递延迟,...,但我没有找到任何关于 Artemis ActiveMQ 在声明处于传递状态的消息之前等待多长时间的文档(等待结束时的自动确认) onMessage 方法长时间执行)必须重新交付。 从日志中我认为它等待 5 分钟,然后在重新传递延迟 2 秒后重新传递消息。

这个时间可以配置吗?

谢谢!

        <subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
            <server name="default">
                <in-vm-connector name="in-vm" server-id="0"/>
                <in-vm-acceptor name="in-vm" server-id="0">
                    <param name="buffer-pooling" value="false"/>
                </in-vm-acceptor>
                <jms-queue name="MyJobsQueue" entries="java:/jms/MyJobsQueue" />
                <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="none" pre-acknowledge="true"/>
            </server>
        </subsystem>
@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "MyJobsQueue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
        @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "5")
})
public class MyJobsListener implements MessageListener {

    //new logger.....
    
    @Override
    public void onMessage(Message m) {
        try {
            logger.info("Received message ({}) (Redelivered:{})", m.getJMSMessageID(), m.getJMSRedelivered());
            
            Thread.sleep(10 * 60 * 1000);
        } catch (InterruptedException e) {
        }
    }
}
2020-11-19 04:00:00 INFO - Received message (ID:5002ad76-2a13-11eb-bedf-005056b94ad2)  (Redelivered:false)
2020-11-19 04:05:00 INFO - Received message (ID:5002ad76-2a13-11eb-bedf-005056b94ad2)  (Redelivered:true)
2020-11-19 04:10:00 INFO - Received message (ID:5002ad76-2a13-11eb-bedf-005056b94ad2)  (Redelivered:true)
2020-11-19 04:15:00 INFO - Received message (ID:5002ad76-2a13-11eb-bedf-005056b94ad2)  (Redelivered:true)
2020-11-19 04:45:24 INFO - Received message (ID:5002ad76-2a13-11eb-bedf-005056b94ad2)  (Redelivered:true)

【问题讨论】:

    标签: java jms wildfly activemq-artemis


    【解决方案1】:

    MDB(就像所有其他类型的 EJB 一样)隐式支持 JTA 事务,一旦 MDB 收到消息,容器就会启动事务。这样做是为了在处理消息时完成的任何事务性工作(例如更新数据库、发送另一个 JMS 消息等)都将成为使用消息本身的事务的一部分。这样,消息就可以成为“工作单元”。

    因此需要注意的是,WildFly 中的默认事务超时时间为 300 秒(即 5 分钟)。一旦事务超时,消息将回滚到队列中并可能重新传递。当然,重新交付的工作方式最终取决于代理的配置。

    在任何情况下,您都可以通过使用此注释禁用 JTA 事务来防止长时间运行的 MDB 出现此类问题:

    @TransactionAttribute(NOT_SUPPORTED)
    

    如果您不想为 MDB 禁用容器管理的事务,您可以通过将 default-timeout 属性添加到 &lt;subsystem xmlns="urn:jboss:domain:transactions:5.0"&gt; 中的 coordinator-environment 元素来更改默认事务超时,例如:

    <coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}" default-timeout="600"/>
    

    但是,请记住,长时间运行的事务是一种反模式,因此我不鼓励您增加超时时间。

    【讨论】:

    • 好的,所以从 JTA 继承的 5 分钟超时 id,好!并感谢您提出禁用事务管理的建议。但是如果我想让容器管理事务怎么办?是否可以增加 wildfly 事务超时?这是个好主意吗?谢谢
    • 我更新了我的答案以解决您的评论。希望有帮助!
    • 我的回答是否解决了您的评论?如果是这样,请将其标记为正确,以帮助将来遇到此问题的其他用户。如果是这样,请详细说明仍然缺少什么。谢谢!
    • 另外,如果打算手动管理事务,可以使用@TransactionManagement(TransactionManagementType.BEAN) stackoverflow.com/questions/14154142/…
    猜你喜欢
    • 2014-05-02
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多