ActiveMQ Artemis 2.10.1忽略了TomEE中的重试设置

时间:2019-12-06 00:31:53

标签: tomee activemq-artemis

我下载了最新的ActiveMQ Artemis 2.10.1(Windows 10,JDK 8),无法使address-settings生效。在网上阅读文档(不多),我通过添加以下内容来编辑broker.xml

<address-settings>
    <address-setting match="BETATESTQ">
        <dead-letter-address>BETATESTQ_DLQ</dead-letter-address>
        <expiry-address>BETATESTQ_EXPIRY</expiry-address>
        <redelivery-delay>30000</redelivery-delay>
        <redelivery-delay-multiplier>1.5</redelivery-delay-multiplier>         
        <redelivery-collision-avoidance-factor>0.15</redelivery-collision-avoidance-factor>
        <max-redelivery-delay>100000</max-redelivery-delay>
        <max-delivery-attempts>999</max-delivery-attempts>      
    </address-setting>   
</address-settings>

<addresses>
    <address name="BETATESTQ_DLQ">
        <anycast>
            <queue name="BETATESTQ_DLQ" />
        </anycast>
    </address>   
    <address name="BETATESTQ_EXPIRY">
        <anycast>
            <queue name="BETATESTQ_EXPIRY" />
        </anycast>
    </address>   
    <address name="BETATESTQ">
        <anycast>
            <queue name="BETATESTQ" />
        </anycast>
    </address>  
</addresses>

创建经纪人时,其他所有默认设置为broker.xml

似乎总是使用redelivery-delaymax-redelivery-delaymax-delivery-attempts的默认值。它确实正确读取了无效字母和到期值。我可以在TomEE日志中看到该消息被重试,并显示在Artemis控制台中,并在完成后移至死信队列。

最初将数据放入队列时,我并没有传递和传递或重试数据(使用最少的Java J2EE代码)。

如何获取不忽略redelivery-delaymax-redelivery-delaymax-delivery-attempts的信息?

我使用Apache TomEE连接到队列(不使用TomEE中的内置ActiveMQ 5.x,而是将其指向ActiveMQ Artemis)

JMS侦听器:

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.*;

@MessageDriven(name = "BETATESTQ", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "BETATESTQ"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") 
})
public class BetaTestQueueListener implements MessageListener, java.io.Serializable {
    private static final long serialVersionUID = 1L;     

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void onMessage(Message rcvMessage) {
        System.out.println("omMessage throw runtime exception");          
        throw new RuntimeException("trigger retry");
    }
}

12/20/19-我为TomEE 8.0.0找到的工作值:

tomee.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tomee>

    <Resource id="artemis" class-name="org.apache.activemq.artemis.ra.ActiveMQResourceAdapter">
        ConnectorClassName=org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory
        ConnectionParameters=host=127.0.0.1;port=61617;needClientAuth=false;sslEnabled=true;keyStorePath=../ssl/server_jks_keystore.jks;keyStorePassword=mypassword;trustStorePath=../ssl/client_jks_truststore.jks;trustStorePassword=mypassword;trustAll=true;verifyHost=false;wantClientAuth=false;needClientAuth=false;keyStoreProvider=JKS;trustSToreProvider=JKS
        UserName=admin
        Password=admin     
        JndiParams=java.naming.factory.initial=org.apache.openejb.core.OpenEJBInitialContextFactory
    </Resource>

    <Resource id="MyJmsConnectionFactory"
              class-name="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory"
              constructor="uri,username,password"
              type="javax.jms.ConnectionFactory">
        uri=tcp://localhost:61617?needClientAuth=false;sslEnabled=true;keyStorePath=C:/apache-tomee-plus-8.0.0/ssl/server_jks_keystore.jks;keyStorePassword=mypassword;trustStorePath=C:/apache-tomee-plus-8.0.0/ssl/client_jks_truststore.jks;trustStorePassword=mypassword;trustAll=true;verifyHost=false;wantClientAuth=false;needClientAuth=false;keyStoreProvider=JKS;trustSToreProvider=JKS
        username=admin
        password=admin
        TransactionSupport=xa
        PoolMaxSize=20
        PoolMinSize=0   
    </Resource>     

    <Resource id="BETATESTQ_DLQ"
              class-name="org.apache.activemq.artemis.api.jms.ActiveMQJMSClient"
              constructor="name"
              factory-name="createQueue"
              type="javax.jms.Queue">
        name=BETATESTQ_DLQ
    </Resource> 
    <Resource id="BETATESTQ"
              class-name="org.apache.activemq.artemis.api.jms.ActiveMQJMSClient"
              constructor="name"
              factory-name="createQueue"
              type="javax.jms.Queue">
        name=BETATESTQ
    </Resource> 
    <Container id="mdb" type="MESSAGE">
        InstanceLimit = -1
        ResourceAdapter = artemis
        ActivationSpecClass = org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec
    </Container>
</tomee>

用于发送JMS消息的Java EE类:

import java.util.*;
import javax.jms.*;
import org.slf4j.*;

public final class JmsPublisherInstance2 implements java.io.Serializable { 
   private static final long serialVersionUID = 1L;
   private static final Logger LOG = LoggerFactory.getLogger(JmsPublisherInstance2.class);

   public void send( String msg,
                     ConnectionFactory connectionFactory,
                     Queue queue ) throws Exception { 
      Session session = null;
      MessageProducer producer = null;
      TextMessage message = null;
      Connection connection = null;
      try {     
            connection = connectionFactory.createConnection();       
            connection.start();
            session = connection.createSession(true, Session.SESSION_TRANSACTED);
            producer = session.createProducer(queue);
            message = session.createTextMessage(msg);
            producer.send(message);
            session.commit();
      }  catch (Exception e) {
         session.rollback();
         LOG.error(e.getMessage(), e);
         throw e;
      }  finally {
          if (session!=null ) {
              session.close();
          }
          if (connection!=null ) {
              connection.close();
          }
      }
   }
}

Java EE侦听器:

import java.io.*;
import javax.annotation.*;
import javax.ejb.*;
import javax.jms.*;

@MessageDriven ( name = "BetaTESTQMDB" , activationConfig = {
    @ActivationConfigProperty(propertyName="destinationType", propertyValue = "javax.jms.Queue") ,
    @ActivationConfigProperty(propertyName="destination", propertyValue = "BetaTESTQ"),
    @ActivationConfigProperty(propertyName="maxSession", propertyValue = "5"),
    @ActivationConfigProperty(propertyName="acknowledgeMode", propertyValue = "Auto-acknowledge")
})

public class BetaTestQueueListener implements MessageListener, java.io.Serializable { 
      private static final long serialVersionUID = 1L;

      @Resource(name="MyJmsConnectionFactory")
      private ConnectionFactory connectionFactory;

      @Resource
      private MessageDrivenContext mdbContext;

      @Resource(name = "BETATESTQ") 
      private javax.jms.Queue betaTestQ;      

      @TransactionAttribute(TransactionAttributeType.REQUIRED)
      public void onMessage(Message rcvMessage) {
            try {
                jmsInstance.send("test message", connectionFactory, betaTestQ);
            } catch (Throwable t) {
                t.printStackTrace();
                mdbContext.setRollbackOnly();
            }
      }
}

1 个答案:

答案 0 :(得分:0)

您似乎正在使用OpenWire JMS客户端。这使事情变得复杂,因为据我所知,OpenWire JMS客户端在客户端本身中实现了重新交付,并且这些重新交付语义是在客户端而非代理方进行配置的。代理没有机会应用任何种类的重新交付策略,因为OpenWire客户端会处理所有事务,并且不会将交付失败通知代理。 This documentation可以帮助您为OpenWire客户端配置重新交付。

也就是说,我建议关注this tutorial。它演示了如何在不构建/部署JCA RA的情况下集成TomEE和ActiveMQ Artemis。这将允许您使用Core JMS客户端而不是OpenWire JMS客户端。

如果要走RA路线,可以通过从mvn verify目录运行examples/features/sub-modules/artemis-ra-rar/来构建ActiveMQ Artemis JCA RA。 RA将位于名为target的{​​{1}}目录中。