2

为了简化问题,我配置了一个只有一个会话的 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

4

0 回答 0