2017-04-30 2 views
0

JBoss EAP 6.2를 사용하는 현재 응용 프로그램에서는 원격 EJB 호출에 의해 트리거되는 많은 일괄 처리 작업이 있습니다. 이러한 작업에 대한 모든 알림 논리를 중앙 집중화하기 위해 일련 화 된 메시지를 전달하여 모든 호출을 MDB를 통해 라우팅하도록 결정합니다. 의도 흐름은 다음과 같습니다 :RTE의 응답 큐에 메시지가 전송되지 않았습니다.

  • 일괄 작업 클라이언트는 원격 큐에 메시지를 전송
  • MDB이 원격 큐, 프로세스 메시지를 수신하고
  • DLQ 모든 시도가있을 때 알림을 처리하도록 구성되어 EJB를 호출 이 고갈되었습니다.
  • 다시 시도 할 때마다 알림을 보내야합니다. 너무 많은 알림을 피하기 간격을 다시 시도하려면, 나는 JMSReplyTo 헤더를 설정하여 답글 큐를 만드는 시도

마지막 지점을 처리하기 위해 충분히 높다.

@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 
     } 
    } 
} 

대답 MDB :

@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 : 흐름 이상으로 시뮬레이션하기 위해, 나는 ... MDB 구현 아래

홈페이지 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(); 
     } 
    } 
} 

** 클라이언트 : 독립-full.xml에서 **

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 
    } 
} 

** 관련 항목 : **

<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> 

지금 MDB의 위의 흐름, 메시지가 수신되지 않습니다 응답 대기열. 세 개의 큐는 모두 동일한 서버에 배포됩니다. 나는 그 이유를 추측하고

은 아래 라인 : 송신 비동기이고 내가 RTE를 던지고

sendToReplyQueue(e.getMessage(), message); 
LOGGER.info("Throwing exception to simulate retry..."); 
throw new RuntimeException(e); 

때문에 (재 시도를 트리거), 메시지는 어떻게 든 전송되지 않습니다. 이 문제를 해결할 방법이 있습니까? 나는 그 이유를 추측하고

답변

0

당신은 RTE를 주석으로 시도 할 수 아래 라인 ......

입니다. 추적 할 로거를 추가하십시오. 응답 수신처가 올바르게 설정되어 있는지 확인하십시오.

또는 메시지

message.setJMSReplyTo(replydestination);  
LOGGER.info("Reply to: " + message.getJMSReplyTo()); 

replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage)); 
    LOGGER.info("exception details sent to reply queue..."); 
큐를 재생할 전송 여부
관련 문제