2017-04-20 5 views
1

내 Apache-camel 기반 앱이 IBM 대기열에서 메시지를 소비합니다. 아래 연결 팩토리에 대한 세부 사항을 소비하고 프로세스 및 메시지 헤더에서 오는 ReplyQueue에 대한 응답을 보낼 수다른 대기열에 메시지를 보내는 방법 IBM MQ 클러스터의 다른 대기열 관리자 및 호스트 이름에 호스트 됨

hostname=host1000 
QManager=QM1000 
Port="some port" 
Channel="common channel" 

낙타 흐름이다.

from(wmq:queue:<INPUT_QUEUE>) 
.bean("processBean") 
.bean("beanToSendMsgToReplyQueue") 

낙타 헤더에서 JMSReplyQueue 아래에 있습니다. 다른 큐 관리자이고이 큐 관리자는 다른 호스트이지만 클러스터 환경에 있음을 알 수 있습니다.

JMSReplyTo = queue://QM1012/TEST.REPLY?targetClient=1 

또한 큐 관리자가 들어오고 있습니다. like

queue://<queue-manager>//<queue-name>?<other parameters> 

아래는 예외적으로 메시지를 보내는 중입니다.

ERROR o.apache.camel.processor.DefaultErrorHandler:215 - Failed delivery for (MessageId: ID-xxxxxxxxx-0-4 on ExchangeId: ID-xxxxxx-42443-1492594420697-0-1). Exhausted after delivery attempt: 1 caught: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: wmq://queue://QM1012/TEST.REPLY?targetClient=1 due to: Failed to resolve endpoint: wmq://queue://TAP2001R5/TEST?targetClient=1 due to: There are 1 parameters that couldn't be set on the endpoint. Check the uri if the parameters are spelt correctly and that they are properties of the endpoint. Unknown parameters=[{targetClient=1}]. Processed by failure processor: FatalFallbackErrorHandler[Pipeline[[Channel[sendTo(Endpoint[wmq://queue:BACKOUT_Q])], Channel[DelegateSync[[email protected]]], Channel[Stop]]]] 

누구든지 다른 호스트에있는 다른 큐 관리자 큐에 메시지를 보내는데 도움이 될 수 있지만 모두 동일한 클러스터에 있습니다. 또한 큐 관리자 이름이 문자열의 중간에 오므로이를 해결하는 방법도 있습니다. 자세한 내용이 필요하면 알려주십시오.

업데이트 -1 :

org.springframework.jms.InvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'QM1000/QUEUE_V1'.; nested exception is com.ibm.msg.client.jms.DetailedInvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'QM1000/QUEUE_V1'. JMS attempted to perform an MQOPEN, but WebSphere MQ reported an error. Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2189' ('MQRC_CLUSTER_RESOLUTION_ERROR'). 

업데이트-2

내가 수 있어요 내가

을 얻고 동일한 큐 관리자로 및 매개 변수

예외 아래

JMSReplyTo = queue://QM1000/QUEUE_V1 없이 시도 일반 javax.jms. * 및 com.ibm.mq.jms. * api를 사용하여 JMSReplyTo에 메시지를 보내십시오. pache 낙타. Camel 사용자/개발자 그룹의 누구라도 낙타 구성 요소를 사용하여 동일한 프로세스를 처리 할 수 ​​있습니까?

@Override 
public void process(Exchange exchange) 
    throws Exception { 

    QueueConnection m_connection = this.connectionFactory.createQueueConnection(); 
    //m_connection.start(); 
    boolean transacted = false; 

    QueueSession session = m_connection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE); 
    TextMessage outMessage = session.createTextMessage(); 
    outMessage.setText(exchange.getIn().getBody()); 
    MQQueue mq = new MQQueue(
     "queue://QM1012/TEST.REPLY"); 
    QueueSender queueSender = session.createSender((MQQueue) mq); 
    queueSender.send(outMessage); 

    /* producerTemplate.send("wmq:" + "queue://QM1012/TEST.REPLY", exchange); */ 
} 
+0

targetClient = 1 JMS는에 RFH2 헤더라고도 JMS 헤더에 대한 IBM MQ 클래스를 추가 할 것을 나타낸다 즉, 원격 응용 프로그램은 JMS 응용 프로그램이 아닐 수 있습니다. Camel 흐름에서 다른 방식으로 지정해야 할 수도 있습니까? – JoshMc

+0

예, targetClient = 1을 다른 방법으로 지정하고 해결할 수 있습니다. 우선 첫번째 문제는 IBM MQ 클러스터의 다른 큐 관리자와 호스트 이름에서 호스팅되는 다른 큐로 메시지를 해석하거나 보내는 방법입니다. – srakshit

+1

wmq : //을 뺀 URI는 특정 큐 관리자에서 JMS의 IBM MQ 클래스에 대한 큐를 지정하는 방법입니다. 나는 너에게 더 많은 것을 돕기 위해 낙타에 익숙하지 않다. MQ 7.1 또는 이전 버전이 지원되지 않거나 MQ 7.1 이상에서 특정 원격 대기열 관리자의 rqmname에 대한 권한을 제공 할 수있는 경우 SCTQ에 대한 권한이 필요합니다. – JoshMc

답변

1

첫째, 덕분에 모든 지원. 사용 사례는 다음과 같습니다 (위의 내용도 마찬가지 임).

Apache Camel을 사용하여 MQ 호스트 (hostname, queueManager, port, channel)에 연결하고 동일한 호스트/Qmanager에 속한 대기열에서 메시지를 소비합니다. 메시지가 replyToQueue (JMSReplyTo) 헤더 값과 함께오고 있습니다. ReplyToQueue (JMSReplyTo)의 값은 다음과 같다.

queue://Different_QueueManager_in_Cluster/TEST.REPLY?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1

지금 문제는 연결 개체 위에 연결하는 동안 다른 큐 관리자와 다른 큐에 응답 메시지를 전송하는 방법 호스트와 큐 관리자를 언급한다.

참고 : 모든 MQ 대기열 관리자는 클러스터 환경에 있습니다.

용액 1 : 예컨대위한

form(wmq:queue:INPUT_MSG_Q) 
.bean(requestProcessor) 
.bean(responseProcessor) 

기본적으로 Apache Camel은 ReplyToQ (JMSReplyTo)를 처리합니다. 당신이 ReplyToQ (JMSReplyTo)에 답장을 보내지 않으려면

주를 소비하면서 다음 disableReplyTo=true를 사용 : 동일한 연결/연결 팩토리를 사용하여, queue://Different_QueueManager_in_Cluster/TEST.REPLY에 전송하는 동안, MQ 클러스터가 해당 메시지를 확인합니다은 지정된로 이동합니다 클러스터에 지정된 큐가있는 큐 관리자. 다음 매개 변수 ?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1과 관련하여 Apache Camel은 자동 응답이 JMSReplyTo 인 동안 임의의 3 자 확인자를 사용하지 않고 자동으로 해결할 수 있습니다.

해결 방법 2 :

해제 자동 disableReplyTo=true를 사용하여 응답 헤더에서 큐 정보를 얻을 수 및 일반 javax.jms를 사용하여 메시지를 보낼 * 및 com.ibm.mq.jms * API를의... 동일 코드는 다음과 같습니다. @Sebastian 브란트 (POST)에 의해 언급 된 바와 같이 변수를 사용 대상 리졸버위한

@Override 
public void process(Exchange exchange) 
    throws Exception { 

    QueueConnection m_connection = this.connectionFactory.createQueueConnection(); 
    //m_connection.start(); 
    boolean transacted = false; 

    QueueSession session = m_connection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE); 
    TextMessage outMessage = session.createTextMessage(); 
    outMessage.setText(exchange.getIn().getBody()); 
    MQQueue mq = new MQQueue(
     "queue://Different_QueueManager_in_Cluster/TEST.REPLY"); 
    QueueSender queueSender = session.createSender((MQQueue) mq); 
    queueSender.send(outMessage); 

    /* producerTemplate.send("wmq:" + "queue://Different_QueueManager_in_Cluster/TEST.REPLY", exchange); */ 
} 

2

두 개의 서로 다른 대기열 관리자와 통신하기를 원할 경우 이에 따라 두 개의 Camel JMS 구성 요소 인스턴스를 정의해야합니다. Camel은 QM1000 또는 QM1012의 의미와 QM 액세스 방법을 마술처럼 알 수 없습니다.

먼저 두 WMQ QM에 대해 두 개의 JMS 연결 팩토리 인스턴스가 필요합니다. 이러한 정보를 얻는 방법은 실행 환경에 따라 다릅니다. JEE 서버에서는 구성 후에 JNDI를 사용하여 연결 풀에 액세스 할 수 있습니다. JMS 풀 설정 방법에 대한 응용 프로그램 문서를 살펴보십시오. 독립 실행 형을 실행하는 경우 XA 트랜잭션을 원하면 Spring JMS 연결 캐싱 또는 Atomikos를 살펴보십시오. QM1000의 CF가 sourceCF이고 QM1012의 경우 targetCF라고 가정합니다.

각 QM에 대해 하나씩 Camel JMS 구성 요소의 인스턴스 두 개를 정의 할 수 있습니다. 연결 팩토리를 JMS 구성 요소 (.setConnectionFactory (...))에 삽입하십시오. id가 "jmssource"인 Camel JMS 구성 요소를 정의하고 sourceCF를 주입한다고 가정하십시오. JMS 구성 요소 ID "jmstarget"에서 targetCF를 주입하십시오. 수행 방법은 환경 (JEE/CDI, Spring, 일반 Java)에 따라 다릅니다. stackoverflow 주위에 봐, 거기에 예제가 있습니다.

이제 구문을 사용하여 낙타 노선에 낙타 JMS의 생산자와 소비자를 지정할 수 있습니다 : 다른 큐 관리자에 댓글을 올리려면 낙타의 JMS 응답-에 논리합니다 (JMSReplyTo 헤더를 사용)를 사용할 수 없습니다

.from("jmssource:INPUT_QUEUE") 
    ... 
    (do some processing) 
    ... 
    .to("jmstarget:QUEUE_V1") 

. JMS 표준에서는 이것이 허용되지 않는다고 생각합니다. 응답 대기열로 보내서 명시 적으로 응답을해야합니다.

targetClient 옵션을 설정하는 대상 해결 유용 할 수 있습니다 :

import org.springframework.jms.support.destination.DynamicDestinationResolver; 
import org.springframework.jms.support.destination.DestinationResolver; 
import javax.jms.Destination; 
import javax.jms.JMSException; 
import javax.jms.Session; 
import com.ibm.mq.jms.JMSC; 
import com.ibm.mq.jms.MQDestination; 

public class WMQDestinationResolver extends DynamicDestinationResolver implements DestinationResolver { 
    private int targetClient = JMSC.MQJMS_CLIENT_JMS_COMPLIANT; 

    public void setTargetClient(int targetClient) { 
    this.targetClient = targetClient; 
    } 

    public Destination resolveDestinationName(Session session, String destinationName, boolean isPubSubDomain) throws JMSException { 
    Destination destination = super.resolveDestinationName(session, destinationName, isPubSubDomain); 
    if (destination instanceof MQDestination) { 
     MQDestination mqDestination = (MQDestination) destination; 
     mqDestination.setTargetClient(targetClient); 
    } 
    return destination; 
    } 
} 
+0

안녕하세요 @ 세바스찬 브란트, 귀하의 제안에 감사드립니다. 여러개의 큐 관리자의 경우 적절한 접근 방식이어야합니다 (다중 낙타 jms 구성 요소 사용). 또한 직접 보낼 수 없습니다 – srakshit

+0

답장 대기열로 직접 보내는 것이 옵션이 아닌 이유를 자세히 설명해 주시겠습니까? Camel 교환 패턴을 InOnly로 변경할 수 있습니다. 그러면 Camel이 자체적으로 회신을 보내지 않습니다. 기술적으로 Camel이 InOut 패턴을 사용하여 응답을 보내거나 InOnly 패턴을 사용하여 명시 적으로 응답하는지 여부는 차이가 없습니다. –

+0

죄송합니다. 마지막 게시물이 불완전합니다. 안녕하세요 @ 세바스찬 브란트, 귀하의 제안에 감사드립니다. 여러개의 큐 관리자의 경우 적절한 접근 방식이어야합니다 (다중 낙타 jms 구성 요소 사용). 또한 낙타 종점에서 targetClient = 1을 직접 보낼 수는 없습니다. Camel JMS 구성 요소 API 설명서에서 몇 가지 정보를 제공했습니다 (섹션 : 대상에 JMS 공급자 옵션 설정하기).Camel의 disableReplyTo = false 기본적으로. 이 기능을 사용하면 잘 작동하며 Camel은 다른 큐 관리자 (클러스터 됨)에있는 큐에 메시지를 보낼 수 있습니다. – srakshit