Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jms 未发送到RTE上回复队列的邮件_Jms_Hornetq_Message Driven Bean - Fatal编程技术网

Jms 未发送到RTE上回复队列的邮件

Jms 未发送到RTE上回复队列的邮件,jms,hornetq,message-driven-bean,Jms,Hornetq,Message Driven Bean,在当前使用JBoss EAP 6.2的应用程序中,我们有许多由远程EJB调用触发的批处理作业。为了集中这些作业的所有通知逻辑,我们决定通过传递序列化消息将所有调用路由到MDB。预期流量如下所示: 批处理作业客户端将消息发送到远程队列 MDB监听这个远程队列,处理消息并调用EJB DLQ配置为在所有重试均已完成时处理通知 筋疲力尽 每次重试时也应发送通知。避免太多 通知,重试间隔足够高 为了处理最后一点,我尝试在JMSReplyTo头中设置一个Reply队列。为了模拟上述流程,我创建了以下MD

在当前使用JBoss EAP 6.2的应用程序中,我们有许多由远程EJB调用触发的批处理作业。为了集中这些作业的所有通知逻辑,我们决定通过传递序列化消息将所有调用路由到MDB。预期流量如下所示:

  • 批处理作业客户端将消息发送到远程队列
  • MDB监听这个远程队列,处理消息并调用EJB
  • DLQ配置为在所有重试均已完成时处理通知 筋疲力尽
  • 每次重试时也应发送通知。避免太多 通知,重试间隔足够高
为了处理最后一点,我尝试在JMSReplyTo头中设置一个Reply队列。为了模拟上述流程,我创建了以下MDB实现

主MDB:

@MessageDriven(name = "MiddleManMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/test"),
      @ActivationConfigProperty(propertyName = "connectorClassName", propertyValue = "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory"),
      @ActivationConfigProperty(propertyName = "connectionParameters", propertyValue = "host=localhost;port=5445"),
      @ActivationConfigProperty(propertyName = "user", propertyValue = "queueuser"),
      @ActivationConfigProperty(propertyName = "password", propertyValue = "queuepassword")
})
public class MiddleManMDB implements MessageListener {

   private static final Logger LOGGER = LoggerFactory.getLogger(MiddleManMDB.class);

   @Resource(name = "java:/JmsXA")
   private ConnectionFactory connectionFactory;

   /*
    * (non-Javadoc)
    * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
    */
   @Override
   public void onMessage(Message message)
   {
      try {

         if (message instanceof TextMessage) {
            LOGGER.info("Received text message --> {}", ((TextMessage)message).getText());
         }

         throw new JMSException("thrown exception");
      }
      catch (Exception e) {
         sendToReplyQueue(e.getMessage(), message);

         LOGGER.info("Throwing exception to simulate retry...");
         throw new RuntimeException(e);
      }
   }

   private void sendToReplyQueue(String errorMessage, Message message)
   {
      Context context = null;
      Connection conn = null;

      LOGGER.info("Sending exception details to reply queue...");

      try {
         context = new InitialContext();

         conn = connectionFactory.createConnection();
         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         Destination jmsReplyTo = message.getJMSReplyTo();
         MessageProducer replyProducer = session.createProducer(jmsReplyTo);
         replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage));

      }
      catch (NamingException | JMSException e) {
         e.printStackTrace();
      }
      finally {
         // close connection and context
      }
   }
}
@MessageDriven(name = "ReplyMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/reply")
})
public class ReplyMDB implements MessageListener {

   private static final Logger LOGGER = LoggerFactory.getLogger(ReplyMDB.class);

   @Override
   public void onMessage(Message message) {
      try {
         if (message instanceof TextMessage) {
            LOGGER.info("Received reply message --> " + ((TextMessage)message).getText());
         }
      }
      catch (JMSException e) {
         LOGGER.error("Error in reply queue...", e);
      }
   }
}
回复MDB:

@MessageDriven(name = "MiddleManMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/test"),
      @ActivationConfigProperty(propertyName = "connectorClassName", propertyValue = "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory"),
      @ActivationConfigProperty(propertyName = "connectionParameters", propertyValue = "host=localhost;port=5445"),
      @ActivationConfigProperty(propertyName = "user", propertyValue = "queueuser"),
      @ActivationConfigProperty(propertyName = "password", propertyValue = "queuepassword")
})
public class MiddleManMDB implements MessageListener {

   private static final Logger LOGGER = LoggerFactory.getLogger(MiddleManMDB.class);

   @Resource(name = "java:/JmsXA")
   private ConnectionFactory connectionFactory;

   /*
    * (non-Javadoc)
    * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
    */
   @Override
   public void onMessage(Message message)
   {
      try {

         if (message instanceof TextMessage) {
            LOGGER.info("Received text message --> {}", ((TextMessage)message).getText());
         }

         throw new JMSException("thrown exception");
      }
      catch (Exception e) {
         sendToReplyQueue(e.getMessage(), message);

         LOGGER.info("Throwing exception to simulate retry...");
         throw new RuntimeException(e);
      }
   }

   private void sendToReplyQueue(String errorMessage, Message message)
   {
      Context context = null;
      Connection conn = null;

      LOGGER.info("Sending exception details to reply queue...");

      try {
         context = new InitialContext();

         conn = connectionFactory.createConnection();
         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         Destination jmsReplyTo = message.getJMSReplyTo();
         MessageProducer replyProducer = session.createProducer(jmsReplyTo);
         replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage));

      }
      catch (NamingException | JMSException e) {
         e.printStackTrace();
      }
      finally {
         // close connection and context
      }
   }
}
@MessageDriven(name = "ReplyMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/reply")
})
public class ReplyMDB implements MessageListener {

   private static final Logger LOGGER = LoggerFactory.getLogger(ReplyMDB.class);

   @Override
   public void onMessage(Message message) {
      try {
         if (message instanceof TextMessage) {
            LOGGER.info("Received reply message --> " + ((TextMessage)message).getText());
         }
      }
      catch (JMSException e) {
         LOGGER.error("Error in reply queue...", e);
      }
   }
}
**死信MDB:**

@MessageDriven(name = "DeadLetterMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/dead")
})
public class DeadLetterMDB implements MessageListener {

   private static final Logger LOGGER = LoggerFactory.getLogger(DeadLetterMDB.class);

   @Override
   public void onMessage(Message message) {
      try {
         LOGGER.info("Message has arrived in dead letter queue");
         LOGGER.info("Current delivery count - {}", message.getIntProperty("JMSXDeliveryCount"));

         if (message instanceof TextMessage) {
            LOGGER.info("Received text message --> {}", ((TextMessage)message).getText());
         }
      }
      catch (JMSException e) {
         e.printStackTrace();
      }
   }
}
**客户:**

public static void main(String[] args) {
   Connection connection = null;
   Context context = null;

   try {
      // create context and connection factory

      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      Destination destination = (Destination) context.lookup("jms/queue/test");
      Destination replyDest = (Destination) context.lookup("jms/queue/reply");
      MessageProducer producer = session.createProducer(destination);
      connection.start();

      TextMessage message = session.createTextMessage("Hello World");
      message.setJMSReplyTo(replyDest);

      producer.send(message);
   }
   catch (NamingException | JMSException e) {
      e.printStackTrace();
   }
   finally {
      // close context and connection
   }
}
**standalone-full.xml中的相关条目:**

<address-settings>
  <address-setting match="jms.queue.testQueue">
      <dead-letter-address>jms.queue.DLQ</dead-letter-address>
      <expiry-address>jms.queue.ExpiryQueue</expiry-address>
      <redelivery-delay>1000</redelivery-delay>
      <max-delivery-attempts>3</max-delivery-attempts>
      <max-size-bytes>10485760</max-size-bytes>
      <address-full-policy>BLOCK</address-full-policy>
      <message-counter-history-day-limit>10</message-counter-history-day-limit>
  </address-setting>
  <address-setting match="jms.queue.replyQueue">
      <redelivery-delay>1000</redelivery-delay>
      <max-delivery-attempts>3</max-delivery-attempts>
      <max-size-bytes>10485760</max-size-bytes>
      <address-full-policy>BLOCK</address-full-policy>
      <message-counter-history-day-limit>10</message-counter-history-day-limit>
  </address-setting>
  <address-setting match="jms.queue.DLQ">
      <redelivery-delay>1000</redelivery-delay>
      <max-delivery-attempts>3</max-delivery-attempts>
      <max-size-bytes>10485760</max-size-bytes>
      <address-full-policy>BLOCK</address-full-policy>
      <message-counter-history-day-limit>10</message-counter-history-day-limit>
  </address-setting>
</address-settings>

<jms-destinations>
  <jms-queue name="testQueue">
      <entry name="queue/test"/>
      <entry name="java:jboss/exported/jms/queue/test"/>
  </jms-queue>
  <jms-queue name="replyQueue">
      <entry name="queue/reply"/>
      <entry name="java:jboss/exported/jms/queue/reply"/>
  </jms-queue>
  <jms-queue name="DLQ">
      <entry name="queue/dead"/>
      <entry name="java:jboss/exported/jms/queue/dead"/>
  </jms-queue>
  <jms-topic name="testTopic">
      <entry name="topic/test"/>
      <entry name="java:jboss/exported/jms/topic/test"/>
  </jms-topic>
</jms-destinations>

由于发送是异步的,并且我正在抛出一个RTE(以触发重试),因此消息不知何故从未发送过。有办法解决这个问题吗?

我猜原因是以下几行

你可以尝试评论RTE。还要添加一些更多的记录器以进行跟踪。检查回复目的地设置是否正确

或消息是否发送到重播队列

  replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage));
  LOGGER.info("exception details sent to reply queue...");