2011년 5월 23일 월요일

Starting Java Messaging System - 5

JMS API

ConnectionFactory
Message Receiver는 MOM과 연결하기 위해서 Connection 객체를 필요로 한다. ConnectionFactory객체는 Connection에 관한 정보를 가지고 있으면서 Connection객체를 생성할 수 있는 Interface이다.
ConnectionFactory 객체의 2가지 종류
- PTP에서 사용하는 QueueConnectionFactory
- PUb/Sub방식에서 사용하는 TopicConnectionFactory이다.
각각의 객체는 JNDI Name으로 등록되며, Program Code에서는 다음과 같이 JNDI Name을 이용하여 찾을 수 있다.
QueueConnectionFactory qConnFactory =
(QueueConnectionFactory)context.lookup("QueueConnectionFactory");
ConnectionFactory에는 createXXXConnection()이라는 method가 존재하는데, 이를 이용하여 Connection객체를 생성할 수 있다.
QueueConnection qConn=qConnFactory.createQueueConnection();

Destination
통신Program에서 일반적으로 접속, 즉 Connection이 일어나려면 IP Address와 Port Number가 필요하다. 하지만 Message System에서는 MOM을 제공하는 Vendor들마다 사용하는 주소방식이 상이하기 때문에 표준을 지정하기가 곤란한다. 따라서 MOM에서는 Destination이라는 객체를 사용하는데, 이것은 Sender나 Receiver가 Message를 주고 받을 곳을 지칭하는 가상 채널정도라고 말할 수 있다.(일반적으로 Destination 객체는 MOM자체를 지칭한다.) PTP에서는 Destination은 보통 Queue라고 불리며, Sub/Pub에서는 Topic이라고 불린다.
Program Code에서는 다음과 같이 Destination객체를 찾을 수 있다.
- Queue queue=(Queue)ctx.lookup("myQueue");
- Topic topic=(Topic)ctx.lookup("myTopic");

Connection
Connection객체는 Sender와 Receiver를 MOM과 연결해 주는 객체이다. 이 연결은 TCP/IP 형태로 이루어진다. 사실 Sender가 MOM에게 Message를 보내려면 Session이라는 객체가 필요한데, 이 객체는 바로 Connection객체를 통해서 얻어진다. Connection객체 역시 PTP의 QueueConnection과 TopicConnection 두 가지 종류가 있다. 사용된 Connection객체는 Program 종료 시 close()를 호출해서 닫아주어야 한다.
- QueueConnection qConn = qConnFactory.createQueueConnection();
- TopicConnection tConn = tConnFactory.createTopicConnection();
- qConn.close();
- tConn.close();

Session
Session은 Message를 생성(Produce)하고 소비(Consume)하기 위한 환경을 제공한다. 특히 Session은 MessageProducer와 MessageConsumer를 생성하며 Temporary Destination객체를 생성한다. Session에는 QueueSession과 TopicSession 두가지 종류가 있다. QueueSession을 생성하기 위해서는 QueueConnection을 이용해야 하고, TopicSession을 생성하기 위해서는 TopicSession을 생성해야 한다.
- QueueSession qSession
=qConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSession tSession
= tConn.createTopicSession(false.Session.AUTO_ACKNOWLEDGE);
사용된 첫 번째 Argument는 Session이 Transaction에 포함되는지 아닌지를 설정한다. 참고로 'true'로 Setting될 경우, 두 번째 Argument는 무시된다. 두 번째 Argument는 전달된 Message의 ACK를 제어하는 내용이다.

Message Producer
Message를 Destination객체에 전달하기 위해서는 Message Producer가 필요하다. PTP에서는 Message Producer를 QueueSender라고 부르며, Pub/Sub에서는 TopicPublisher라고 부른다.
QueueSession의 createSender()를 이용하면 QueueSender 객체를 생성할 수 있고, TopicSession의 createPublisher()를 이용하면 TopicPublisher 객체를 만들 수 있다.
- QueueSender qSender = qSession.createSender(Queue);
- TopicPublisher tPublisher = tSession.createPublisher(Topic);
이렇게 생성된 Message Producer를 통해 Message를 전송하기 위해서는 다음처럼 send()나 publish()를 이용한다.
- qSender.send(Message);
- tPublisher.publish(Message);

Message Consumer
Message Producer로 부터 생성되어 전해진 Message를 받기 위해서는 Message Consumer가 필요하다. PTP에서는 Message Consumer를 QueueReceiver라고 부르며, Pub/Sub에서는 TopicSubscriber라고 부른다. QueueSession의 createReceiver()를 이용하면 QueueReceiver 객체를 생성할 수 있고, TopicSession의 createSubscriber()를 이용하면 TopicSubscriber객체를 만들 수 있다. Message를 받는 방식에는 다음과 같은 동기식 방식과 비동기식 방식이 있다.
동기식 방식: 이 방식을 사용하는 Client가 Message를 소비하기 위해서 receiver()를 호출한다. receiver()가 호출되면 Client는 Message가 모두 도착하거나 Time-Out될 때까지 Block상태에 놓인다.
비동기식 방식 : 이 방식을 사용하는 Client는 Event Delegation Model을 사용하여 Event Handler를 등록할 수 있다. Event Handler는 MessageListener Interface를 implements해야 한다. Message가 목적지에 도착할 때 마다 onMessage()가 자동 호출된다.
다음은 Program Code에서 각각의 Message Consumer를 생성하는 예이다.
- QueueReceiver qReceiver=qSession.createReceiver(Queue);
- TopicSubscriber tSubscriber = tSession.createSubscriber(Topic);
이렇게 생성된 Message Consumer를 통해 Message를 전송 받기 위해서는 다음처럼 먼저 Connection객체가 가지고 있는 start()를 호출해야 한다. 그 후, QueueReceiver나 TopicSubscriber에 있는 receive()를 이용하면 Message를 받을 수 있다.
- qConn.start();
- TextMessage tMessage = (TextMessage) qReceiver.receive(1);
receive()의 첫 번째 Argument는 Time-Out을 의미한다.(1/1000 초)
다음 Code는 비동기식 방식을 이용하여 Message를 소비한다. 다음의 Code처럼 TopicSubscriber 객체의 setMessageListener() 를 이용해 Event handler에게 Message소비를 위임한다.
- tSubscriber.setMessageListener(listener);

Message 객체
Message 객체는 JMS에서 Application Program사이에 주고 받는 Data를 의미한다. 이같은 Message객체는 3부분으로 나눌 수 있다.
- Header : JMS Client와 MOM Server에서 사용되는 통신정보를 가지고 있다.
- Property : Option항목으로 JMS Client나 MOM Server의 고유한 정보가 포함되어 있다.
- Body : Message의 내용이 포함되어 있다.
JMS에는 다음과 같이 크게 5가지 형태의 Message Type이 있다.
- TextMessage : 문자열 Data로서 String Type이다.
- MapMessage : 이름과 값의 쌍으로써, 이름은 String Type이고 값은 Primitive Type이다.
- ByteMessage : Byte Stream Data Type
- ObjectMessage : Serialize Object
- Message : Body가 존재하지 않는 Message
Message는 오직 한번만 정확하게 전달되어야 한다.
JMS는 Message가 신뢰성을 가지고 전달될 수 있도록 다음과 같은 다양한 level을 지원한다.
- Controlling Message Acknowledgement (Message ACK 제어)
- Specifying Message Persistence (Message 지속성 기술)
- Message Priority Level (Message 우선순위)
- Message Validate Duration (Message 유효기간)
- Temporary Destination (임시 목적지 사용)
Message ACK제어
MOM은 Client가 Message를 잘 받았다는 확인을 받은 후에야 Message소비가 성공적으로 끝났다고 판단한다. 성공적인 Message 소비는 다음과 같은 3단계를 거친다.
- Client가 Message를 받는다
- Client가 Message를 처리한다
- MOM에게 Message를 잘 받았다는 확인 Message를 전송한다.
Transaction이 포함된 Session인 경우 Transaction이 Commit되면 확인 Message는 자동적으로 전달된다. 만약 Transaction이 Rollback되면 소비된 모든 Message는 다시 Client에게 전달된다. Transaction이 포함된 Session이 아닌 경우는 createQueueSession()이나 createTopicConnection()의 Argument로 어떤 값을 사용하느냐에 따라 확인 Message를 전달하는 방식이 달라진다.
- AUTO_ACKNOWLEDGE : Client가 receive()를 성공적으로 수행하거나 MessageListener의 Message가 잘 처리된 경우 자동적으로 확인 Message가 전달된다.
- CLIENT_ACKNOWLEDGE : Client가 인위적으로 acknowledge()를 호출해야 확인 Message가 전달된다.
- DUPS_OK_ACKNOWLEDGE :확인 Message를 나중에 보낸다. 이 경우엔, 동일한 Message가 여러 번 전달될 수도 있다.
Message 지속성 기술
Message가 전달되는 도중 JMS가 중단될 수 있다. 이 경우, Message는 사라질 수도 있고 유지될 수도 있다. JMS API에는 이것을 기술하기 위한 2가지 mode를 제공한다.
- PERSISTENT Delivery Mode : MOM은 MOM Service가 중단되는 경우, Message가 실종되지 않도록 한다. 이 모드는 Default속성이다.
- NON_PERSISTENT Delivery Mode : PERSISTENT Delivery Mode와 반대되는 속성이다.
이같은 mode를 설정할 수 있는 방법에는 2가지가 있다.
- MessageProducer Interface의 setDeliveryMode()를 이용한다.
- send()와 publish()의 Argument를 이용한다.
Message 우선순위
중요한 Message나 급한 Message를 먼저 처리할 수 있도록 우선순위를 지정할 수 있다. 우선 순위는 0~9까지로 10단계로 되어 있으며, 0이 가장 낮은 우선순위이고, 9가 가장 높은 우선 순위이다. 4순위가 기본 순위이다. 우선순위를 지정하는 방법에는 2가지가 있다.
- send()와 publish()에 우선순위를 기술한다.
- MessageProducer 객체의 setPriority()를 이용한다.

댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...