JMS를 사용하도록 엔터프라이즈 애플리케이션 설계
비동기 메시징을 위해 JMS API를 직접 사용하는 엔터프라이즈 애플리케이션을 설계할 때 고려해야 할 다수의 사항이 있습니다.
프로시저
- 메시징 조작의 경우 Sun의 javax.jms 패키지에 정의된 인터페이스에 대해 참조만 사용하는 애플리케이션 프로그램을 작성해야 합니다. JMS는 기초 전송으로 맵핑되는 메시징의 일반 보기를 정의합니다. JMS를 사용하는 엔터프라이즈 애플리케이션은 Sun의 javax.jms 패키지에 정의된 다음 인터페이스를 사용합니다.
- Connection
- 기초 전송에 대한 액세스를 제공하고 세션을 작성하는 데 사용됩니다.
- 세션
- MessageProducers 및 MessageConsumers를 작성하는 데 사용되는 메소드를 포함하여 메시지 생성 및 처리를 위한 컨텍스트를 제공합니다.
- MessageProducer
- 메시지를 보내는 데 사용됩니다.
- MessageConsumer
- 메시지를 수신하는 데 사용됩니다.
일반적 JMS 인터페이스는 지점간 및 공개/등록 동작을 위한 다음 추가 특정 버전으로 하위 분류됩니다.표 1. JMS 공통 인터페이스의 지점간 및 공개/등록 버전. 이 테이블의 첫 번째 열은 JMS 공통 인터페이스를 나열하고, 두 번째 열이 해당 지점간 인터페이스를 나열하고, 세 번째 열이 해당 공개/등록 인터페이스를 나열합니다. JMS 공통 인터페이스 지점간 인터페이스 공개/등록 ConnectionFactory QueueConnectionFactory TopicConnectionFactory Connection QueueConnection TopicConnection 목적지 큐 토픽 세션 QueueSession, TopicSession, MessageProducer QueueSender TopicPublisher MessageConsumer QueueReceiver,
QueueBrowserTopicSubscriber 이들 JMS 인터페이스 사용에 대한 자세한 정보는 IBM MQ Information Center의 Java™ 메시지 서비스 문서 및 Java 사용 절을 참조하십시오.
J2EE 스펙의 "JMS(Java Message Service) 요구사항" 절은 웹 및 EJB 컨테이너에서 호출되어서는 안되는 메소드의 목록을 제공합니다.javax.jms.Session method setMessageListener javax.jms.Session method getMessageListener javax.jms.Session method run javax.jms.QueueConnection method createConnectionConsumer javax.jms.TopicConnection method createConnectionConsumer javax.jms.TopicConnection method createDurableConnectionConsumer javax.jms.MessageConsumer method getMessageListener javax.jms.MessageConsumer method setMessageListener javax.jms.Connection setExceptionListener javax.jms.Connection stop javax.jms.Connection setClientID
이 메소드 제한은 javax.jms.IllegalStateException 예외를 처리하여 WebSphere® Application Server에서 실시됩니다.
- 애플리케이션은 WebSphere Application
Server에 관리 오브젝트로 사전 정의된 JMS 자원을 참조합니다.
엔터프라이즈 애플리케이션에서 사용하는 JMS 자원의 세부사항은 WebSphere Application Server에 정의되고 WebSphere 관리 지원에 의해 JNDI 네임스페이스로 바인드됩니다. 엔터프라이즈 애플리케이션은 JNDI 네임스페이스에서 이러한 오브젝트를 검색하고 오브젝트 구현에 대해 알 필요 없이 이를 사용할 수 있습니다. 이에 따라, 엔터프라이즈 애플리케이션을 변경하지 않고도 JMS 자원에 의해 정의된 기초 메시징 아키텍처를 변경할 수 있습니다.
표 2. 지점간 및 공개/등록 메시징을 위한 JMS 자원. 이 테이블의 첫 번째 열은 지점간 메시징을 위한 JMS 자원을 나열하고 두 번째 열이 공개/등록을 위한 JMS 자원을 나열합니다. 지점간 공개/등록 ConnectionFactory(또는 QueueConnectionFactory)
큐ConnectionFactory(또는 TopicConnectionFactory)
토픽연결 팩토리는 JMS 제공자에서 메시징 시스템으로 연결을 작성한 후 연결을 작성하는 데 필요한 구성 매개변수를 캡슐화하는 데 사용됩니다.
- 성능을 항샹시키기 위해 Application Server는 JMS 제공자와의 연결 및 세션을 풀합니다. 애플리케이션에 적합하게 연결 및 세션 풀 특성을 구성해야 합니다. 그렇지 않은 경우, 원하는 연결 및 세션 작동을 가져올 수 없습니다.
- 애플리케이션은 JMS 연결, 세션, 생성자 또는 소비자를
캐시해서는 안됩니다. WebSphere Application Server는
Bean 또는 서블릿이 완료되면 이러한 오브젝트를 닫기 때문에 캐시된 오브젝트를
사용하려는 모든 시도가 실패하고 javax.jms.IllegalStateException 예외가 발생합니다.
성능을 향상시키기 위해 애플리케이션은 JNDI에서 검색한 JMS 오브젝트를 캐시할 수 있습니다. 예를 들어, EJB 또는 서블릿은 JMS ConnectionFactory를 한 번만 검색해야 하지만 각 인스턴스화에 대해 createConnection 메소드를 호출해야 합니다. JMS 제공자가 연결 및 세션에 대해 풀링으로 영향을 미치기 때문에 성능에 영향이 없어야 합니다.
- 지속 불가능한 등록자는 등록자가 작성될 때 있던 것과 동일한 트랜잭션 컨텍스트(예: 글로벌 트랜잭션 또는 지정되지 않은 트랜잭션 내용)에서만 사용될 수 있습니다.
- 기본 메시징 제공자와 지속 가능한 등록 사용. JMS 주제의 지속 가능한 등록을 이용하면
등록자가 서버에 연결되지 않은 기간이 지나도 이 주제에 공개된 모든 메시지의
사본을 수신할 수 있습니다. 따라서
등록자 애플리케이션은 서버에서 오랜 시간 연결이 끊어진 상태에서도 조작한 후에
서버에 다시 연결하고 끊어진 동안 공개된 메시지를 처리할 수 있습니다.
애플리케이션이
지속 가능한 등록을 작성하면 이는 관리자가 관리 콘솔을 통해 표시하고 활동할 수 있는
런타임 목록에 추가됩니다. 각 지속 가능한 등록에는 고유 ID, clientID##subName이 있습니다. 여기서
- clientID
- 연결 및 해당 오브젝트와 애플리케이션에 대해 JMS 제공자의 클라이언트로 유지되는 메시지를 연관시키는 데 사용되는 클라이언트 ID. 런타임 관리를 위해 연관된 애플리케이션과 지속 가능 등록을 관련시켜야 하는 경우 애플리케이션을 식별하는 데 도움을 주는 이름 지정 규칙을 사용해야 합니다.
- subName
- 제공된 클라이언트 ID 내에서 지속 가능한 등록을 고유하게 식별하는 데 사용되는 등록 이름.
메시지 구동 Bean이 작성한 지속 가능한 등록의 경우 JMS 활성화 스펙에서 이들 값이 설정됩니다. 기타 지속 가능한 등록의 경우에는 JMS 연결 팩토리에서 클라이언트 ID가 설정되고 createDurableSubscriber 조작에서 애플리케이션이 등록 이름을 설정합니다.
지속 가능한 등록을 주제로 작성하기 위해 애플리케이션은 JMS API에 정의된 createDurableSubscriber 조작을 사용합니다.public TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String subName, java.lang.String messageSelector, boolean noLocal) throws JMSException
- 주제
- 등록할 JMS 주제의 이름. 적합한 JNDI 항목을 찾아서 발견되는 것과 같이 javax.jms.Topic 인터페이스를 지원하는 오브젝트의 이름입니다.
- subName
- 이 등록을 식별하는 데 사용되는 이름
- messageSelector
- 특성이 메시지 선택기 표현식에 일치하는 메시지만이 소비자에게 전달됩니다. 널 또는 비어 있는 문자열의 값은 모든 메시지를 전달해야 함을 나타냅니다.
- noLocal
- true로 설정하면 이 매개변수가 지속 가능한 등록자와 동일한 연결에서 공개된 메시지의 전달을 방해합니다.
애플리케이션은 하나의 주제와 subName 매개변수만을 선택하는 createDurableSubscriber 조작의 두 인수 양식을 사용할 수 있습니다. 이 선택적 호출은 이전에 표시되는 것으로서 직접적으로 네 개의 인수 버전을 호출하지만 messageSelector를 널에 설정하고(모든 메시지가 전달되도록) noLocal을 false로 설정합니다(연결에서 공개된 모든 메시지가 전달되도록). 예를 들어, mySubscription의 등록 이름으로 myTopic이라는 주제에 지속가능한 등록을 작성합니다.session.createDurableSubscriber(myTopic,"mySubscription");
createDurableSubscription 조작이 실패하는 경우 문제의 원인에 대한 자세한 정보가 표시된 메시지 및 링크된 예외를 제공하는 JMS 예외가 발생합니다.
지속 가능한 등록을 삭제하기 위해 애플리케이션은 JMS API에 정의된 등록 취소 조작을 사용합니다.
정상적인 작동 상태에서는 지속 가능한 등록에 대해 한 번에 최대 하나의 활성(연결된) 등록자가 있을 수 있습니다. 그러나, 등록자 애플리케이션은 장애 복구 및 로드 밸런스 목적으로 복제된 Application Server에서 실행 중일 수 있습니다. 이 경우 다수의 동시 이용자가 있을 수 있는 공유 지속 가능한 등록을 제공하기 위해 "하나의 활성 등록자" 제한이 제기됩니다.
지속 가능한 등록의 애플리케이션 사용에 대한 자세한 정보는 JMS 스펙에서 "지속 가능한 등록 사용" 섹션을 참조하십시오.
- 필요한 메시지 선택기를 결정하십시오. JMS 메시지 선택기 메커니즘을 사용하여 수신 호출에 의해 메시지 서브세트가 리턴되도록 대기열에서 이 서브세트를 선택할 수 있습니다. 선택기는 JMS 메시지 헤더의 필드와 메시지 특성의 필드를 참조할 수 있습니다.
- 수신된 메시지에 대한 작업. 메시지를 수신하면, 애플리케이션의 비즈니스 로직에 필요한 대로 메시지에 대해
작업을 수행할 수 있습니다. 일부의 일반적인 JMS 조치는 메시지 유형이 올바른지
점검하고 메시지 내용을 추출하는 것입니다. 메시지 본문에서 내용을 추출하려면
일반 메시지 클래스(수신 메소드의 선언된 리턴 유형)에서 TextMessage와 같은
더 구체적인 서브클래스로 캐스트하십시오. 예기치 않은 오류를 적절하게 처리할 수 있도록
메시지 클래스를 캐스트하기 전에 항상 테스트하는 것이 바람직합니다.
이 예제에서 instanceof 연산자는 수신된 메시지가 TextMessage 유형인지 확인하기 위해 사용됩니다. 그런 다음 TextMessage 서브클래스로 캐스트하여 메시지 컨텐츠가 추출됩니다.
if ( inMessage instanceof TextMessage ) ... String replyString = ((TextMessage) inMessage).getText();
- 기본 메시징 제공자를 사용하는 JMS 애플리케이션은 어떤 제한도 없이 WebSphere Application Server 버전 5 임베디드 메시징 또는 IBM MQ 에서 수신된 메시지의 컨텐츠에 액세스할 수 있습니다.
- JMS 애플리케이션은 JMS_IBM* 등록 정보의 전체 세트에 액세스할 수 있습니다. 이들 특성은 기본 메시징 제공자, V5 기본 메시징 제공자 또는 IBM MQ 제공자가 제공하는 자원을 사용하는 JMS 애플리케이션에
대한 값입니다.
IBM MQ 에 의해 처리되는 메시지의 경우 JMS_IBM* 특성이 동등한 MQMD(IBM MQ Message Descriptor) 필드에 맵핑됩니다. JMS_IBM* 특성 및 MQMD 필드에 대한 자세한 정보는 IBM MQ Information Center의 Java 사용 절을 참조하십시오.
- JMS 애플리케이션은 보고 메시지를 관리 요청/응답 처리 양식으로 사용하여 생성자의 전송 조작의 출력과 메시지의 결말에 대한 원격 피드백을 생성자에게 제공할 수 있습니다. JMS 애플리케이션은 JMS_IBM_Report_Xxxx 메시지 특성을 사용하여 전체 범위의 보고서 옵션을 요청할 수 있습니다. JMS 보고서 메시지 사용에 대한 자세한 정보는 JMS 보고서 메시지의 내용을 참조하십시오.
- JMS 애플리케이션은 JMS_IBM_Report_Discard_Msg
특성을 사용하여 요청 메시지를 대상 큐에 전달할 수 없는 경우 이들 메시지의
처리 방식을 제어할 수 있습니다.
- MQRO_Dead_Letter_Queue
- 이것은 기본값입니다. 전달 불가능한 대기열에 요청 메시지를 작성했습니다.
- MQRO_Discard
- 요청 메시지를 버려야 합니다. 이는 일반적으로 MQRO_Exception_With_Full_Data와 함께 사용되어 전달할 수 없는 요청 메시지를 전송자에게 되돌려 보냅니다.
- 리스너를 사용하여 비동기식으로 메시지 수신. 서블릿 또는 엔터프라이즈 Bean이 아닌
클라이언트에서 QueueReceiver.receive()를 호출하는 방법 이외의 다른 방법은 적합한 메시지가 사용 가능할 때
자동으로 호출되는 메소드를 등록하는 것입니다. 예를 들면, 다음과 같습니다.
... MyClass listener =new MyClass(); queueReceiver.setMessageListener(listener); //application continues with other application-specific behavior. ...
메시지가 사용 가능하면 리스너 오브젝트에서 onMessage() 메소드로 검색됩니다.import javax.jms.*; public class MyClass implements MessageListener { public void onMessage (Message message) { System.out.println("message is "+message); //application specific processing here ... } }
비동기 메시지 전달의 경우 애플리케이션 코드는 메시지 수신 실패로 인해 발생한 예외를 발견할 수 없습니다. 이는 애플리케이션 코드가 receive() 메소드를 명시적으로 호출하지 않기 때문입니다. 이 상황에 대처하기 위해 onException() 메소드를 구현하는 클래스의 인스턴스인 ExceptionListener를 등록할 수 있습니다. 오류가 발생하면 유일한 매개변수로 전달된 JMSException을 사용하여 이 메소드를 호출합니다.
비동기 메시지 수신을 위해 리스너를 사용하는 방법에 대한 자세한 내용은 Java 메시지 전달 서비스 문서를 참조하십시오.
참고: 사용자 고유의 JMS 리스너 클래스를 개발하는 대신 메시지 구동 Bean을 사용하는 프로그래밍에 설명된 대로 메시지 구동 Bean을 사용할 수 있습니다. 서버측 애플리케이션 컴포넌트에서 JMS receive()를 수행하고, 이 receive() 호출이 동일한 서버에서 배치되는 다른 애플리케이션 컴포넌트에 의해 생성된 메시지에서 대기하는 경우 주의하십시오. 이러한 JMS receive()는 동기식이므로 응답 메시지를 수신할 때까지 차단됩니다.
애플리케이션 디자인의 이런 유형은 작업 스레드의 전체 설정이 수신 컴포넌트에 의해 지쳐버릴 수 있는 이용자 또는 생성자 문제점으로 이어질 수 있으며, 그것을 위해 응답 JMS 메시지를 생성할 애플리케이션 구성요소를 신속히 처리한 어떤 사용 가능한 작업자 스레드도 남기지 못하면서, 응답을 기다려 차단됩니다. 예를 들어, 서블릿 및 메시지 구동 Bean은 동일한 서버에 배치됩니다. 이 서블릿이 요청을 디스패치하면, 메시지 구동 Bean이 서비스하는 큐로 메시지를 전송합니다. 즉, 서블릿이 생성한 메시지는 메시지 구동 Bean의 onMessage() 메소드에서 소비합니다. 이어 서블릿은 receive()를 발행하고 임시 ReplyTo 큐에서 응답을 대기합니다. 메시지 구동 Bean onMessage() 메소드는 데이터베이스 조회를 수행하고 임시 큐의 서블릿으로 응답을 다시 전송합니다. 동시에 많은 수의 서블릿 요청이 발생하면(서버 작업자 스레드의 수에 비해), 서블릿 요청을 디스패치하고 메시지를 전송하며 응답을 대기하기 위해 사용 가능한 모든 서버 작업자 스레드가 사용될 수 있습니다. Application Server는 현재 보류 중인 메시지 구동 Bean을 처리하기 위한 스레드가 남아 있지 않은 조건을 입력합니다. 그러므로, 서블릿이 기다리고 있는 응답이 모두 차단되기 때문에, 서버는 정지되고, 이는 애플리케이션 장애에 적합 유도입니다.
기능한 솔루션은 다음과 같습니다.
- 작업자 스레드의 수(서버 영역 당 스레드 수 * 서버 당 서버 영역 수)가 receive()를 수행하는 애플리케이션 컴포넌트의 동시 디스패치 수를 초과하는지 확인하여, 언제나 작업자 스레드가 메시지 생성 컴포넌트를 디스패치할 수 있도록 하십시오.
- 수신기 애플리케이션 컴포넌트를 생성자 애플리케이션 컴포넌트가 아닌 별도의 서버에 배치하는 애플리케이션 토폴로지를 사용하십시오. 이러한 배치 시나리오에서도 계속 작업자 스레드 사용을 주의 깊게 고려해야 하지만 이러한 분리를 통해 메시지 수신 컴포넌트가 차단할 수 없는 스레드가 언제나 존재하도록 할 수 있습니다. 복수 애플리케이션을 설치한 Application Server와 같이 다른 상호 작용을 고려해야 할 수 있습니다.
- 애플리케이션이 작업자 스레드의 생산자 구성요소와 경쟁할 클라이언트 구성요소에서의 메시지 수신을 수행하도록 다시 포함시키십시오. 또한, 클라이언트 컴포넌트는 J2EE 서버에서 금지되는 비동기(비중단) 수신을 수행할 수 있습니다. 예를 들어, 이전 예제 애플리케이션은 메시지를 큐에 보내고 MDB로부터 응답을 기다리는 클라이언트를 가지고 있도록 리팩토링될 수 있습니다.
- IBM MQ 또는 버전 5 임베디드 메시징 지원과 함께 인증을 사용하려는 경우 12자보다 긴 사용자 ID를 가질 수 없습니다. 예를 들어, 기본 Windows NT 사용자 ID, administrator는 13자이기 때문에 WebSphere 내부 메시징에 사용하기에는 올바르지 않습니다.
- EJB 스펙에 정의된 대로 다음과 같은 사항이
createxxxSession 호출 시 플래그 사용에 적용됩니다.
- createxxxSession에 전달된 트랜잭션 플래그는 글로벌 트랜잭션 내에서 무시되고 모든 작업은 트랜잭션의 일부로 수행됩니다. 트랜잭션 외부에서 트랜잭션 플래그가 사용되고, true로 설정된 경우 애플리케이션은 session.commit() 및 session.rollback()을 사용하여 작업 완료를 제어합니다. EJB2.0 모듈에서 트랜잭션 플래그가 true로 설정되어 있고 XA 트랜잭션 외부에 있으면 세션은 WebSphere 로컬 트랜잭션에 포함되고, 애플리케이션에 의해 커미트되거나 롤백되지 않은 경우에는 메소드의 분석되지 않은 조치 속성이 JMS 작업에 적용됩니다.
- 클라이언트는 수신확인 메시지에 Message.acknowledge()를 사용할 수 없습니다. CLIENT_ACKNOWLEDGE의 값이 createxxxSession 호출에 전달되면, 메시지는 자동으로 Application Server에 의해 수신확인되고 Message.acknowledge()가 사용되지 않습니다.
- 애플리케이션이 IBM MQ를 외부 JMS 제공자로 사용하기 원하는
경우 컨테이너 관리 트랜잭션(CMT) 내에서 메시지를 보내십시오.
IBM MQ를 외부 JMS 제공자로 사용할 때, 사용자 관리 트랜잭션 내에서 전송된 메시지는 트랜잭션이 커미트하기 전에 도달할 수 있습니다. 이것은 IBM MQ를 외부 JMS 제공자로 사용할 때만 발생하며, 사용자 관리 트랜잭션 내에서 IBM MQ 큐로 메시지를 보낼 수 있습니다. 메시지는 트랜잭션 확약 전에 대상 큐에 도착합니다.
이 문제점의 원인은 IBM MQ 자원 관리자가 사용자 관리 트랜잭션에 나열되지 않았기 때문입니다.
솔루션은 컨테이너 관리 트랜잭션을 사용됩니다.


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tmj_desap
파일 이름:tmj_desap.html