我在wildfly21.0.0中配置了一个jms队列和几个虚拟机连接器/接受器。然后我有了一个消息驱动bean(mdb),它最多有5个并发会话,而不是处理接收到的消息和做一些肮脏的工作。在某些情况下,这项工作需要5分钟以上的时间,而且队列会将消息重新传递给mdb,从而造成混乱。
我理解了重新传递的概念,重新传递延迟,…,但是我没有找到任何关于artemisactivemq在声明处于传递状态(在onmessage方法long execution结束时等待自动确认)的消息必须重新传递之前等待多长时间的文档。从日志中,我认为它等待了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)
1条答案
按热度按时间uyhoqukh1#
mdb(就像所有其他类型的ejb一样)隐式地支持jta事务,一旦mdb收到消息,容器就会启动一个事务。这样做是为了在处理消息时完成的任何事务性工作(例如,更新数据库、发送另一条jms消息等)都将成为使用消息本身的事务的一部分。这样一来,消息就可以成为“工作单元”
因此需要注意的是,wildfly中的默认事务超时是300秒(即5分钟)。一旦事务超时,消息将回滚到队列并可能重新传递。当然,再交付的工作方式最终取决于代理的配置。
在任何情况下,都可以通过禁用具有以下注解的jta事务来防止长时间运行的MDB出现此类问题:
如果不想为mdb禁用容器管理的事务,可以通过添加
default-timeout
属性为coordinator-environment
元素<subsystem xmlns="urn:jboss:domain:transactions:5.0">
,例如:但是,请记住,长时间运行的事务是一种反模式,因此我不鼓励您增加超时时间。