为了简化问题,我配置了一个只有一个会话的 MDB。
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.slf4j.Logger;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/adwordsReportRequest"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "veiculo = 'adwords'"),
@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1"),
@ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "7500") })
public class ReportRequestReceiveDispatcherAdwords implements MessageListener {
@Resource
private MessageDrivenContext mdc;
@Inject
private Logger logger;
private Integer count = 0;
public ReportRequestReceiveDispatcherAdwords() {
// TODO Auto-generated constructor stub
}
public void onMessage(Message inMessage) {
TextMessage msg = null;
String text = null;
try {
if (inMessage instanceof TextMessage) {
msg = (TextMessage) inMessage;
text = msg.getText();
if (count >= 10 && count <= 100) {
logger.error("Count: {} - {} - Marcando como erro!", ++count, text);
throw new RuntimeException("teste de erro");
} else
logger.info("Count: {} - {}", ++count, text);
} else {
logger.warn("Message of wrong type: " + inMessage.getClass().getName());
}
} catch (Exception e) {
mdc.setRollbackOnly();
}
}
}
队列配置了 3 次尝试和两次尝试之间的 2 分钟延迟。
<address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-delivery-attempts="3" redelivery-delay="120000" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
使用队列中的 600 条消息执行此代码:
14:10 --> it stopped the processing at the first error.
14:12 --> processes 3 messages and stops.
14:14 --> processes 10 messages and stops.
14:16 --> processes 14 messages and stops.
14:18 --> processes 10 messages and stops.
14:20 --> processes 16 messages and stops.
14:22 --> processes 9 messages and stops.
14:24 --> processes 8 messages and stops.
14:26 --> processes 7 messages and stops.
14:28 --> processes 6 messages and stops.
14:30 --> processes 6 messages and stops.
14:32 --> processes 6 messages and stops.
14:34 --> It goes out of the loop that generates error, so it finish the processing of the other messages until the queue is empty.
如果队列中仍有消息,为什么 MDB 会停止?当消息在回滚后返回队列时,它会进入顶部阻塞测试吗?这对我来说没有任何意义。我找不到任何描述此行为的文档。
根据规范:
其他后续消息会定期发送,只有取消的消息会在延迟后异步发送回队列。 https://activemq.apache.org/artemis/docs/2.0.0/undelivered-messages.html