JMS(Java Message Service)
메시징 시스템은 응용프로그램 간에 비동기적으로 메시지를 교환할 수 있는 방법을 제공해준다.
비즈니스에서 메시징 서비스를 이용하려면 MOM(Message Oriented Middleware)가 필요하다.
MOM은 메시지를 전달할 수 있으며, 메시지 전달을 비동기적으로 처리할 수 있는 특징이 있는 시스템이다.
JMS는 각 회사에서 만든 MOM 시스템의 공통적인 부분을 표준화함으로써 공통된 API를 사용할 수 있게 한다.
웹로직 서버는 MOM 기능을 제공한다.
메시징 서비스를 이용함으로써 얻을 수 있는 장점으로는 통신이 비동기적으로 이뤄지기 때문에 클라이언트에서는 작업 여러 개를 기다릴 필요 없이 처리할 수 있다는 것이다.
메시징 서비스는 다음과 같은 종류의 서비스를 제공한다.
P2P(Peer to Peer)
여러 개의 클라이언트(메시지 센더)에서 보낸 메시지를 MOM의 메시지 큐(Message Queue)에 차례대로 저장한 후, 메시지 리시버(Message Receiver)가 큐의 내용을 하나씩 읽어 들여 처리할 수 있는 방식을 말한다. 메시지 큐는 메시지 리시버가 메시지를 읽어갈 때까지, 혹은 유효 시간이 경과되기 전까지 메시지를 저장하게 된다.
Pub/sub
발행자/가입자의 약자이다.
메시지 센더에서 메시지를 MOM에게 전달(출판)하면, 주제에 등록된 클라이언트에게 메시지가 전달(구독)되는 방식을 말한다.
JMS란
MOM을 공통적으로 이용하기 위한 API
JMS API를 이용하기 위해서는 JMS명세를 알아야 한다.
JMS 명세에 따르면 JMS를 이용하는 응용 프로그램은 다음과 같은 요소로 구성된다.
각각의 요소는 API에서 제공하는 객체가 될 수도 있으며 어떤 부분은 응용 프로그램일 수 있다.
운영도구(Administrative Tool)
커넥션 팩토리(Connection Factories)
목적지(Destinations)
커넥션(Connection)
세션(Session)
메시지 생산자(Message Producer)
메시지 소비자(Message consumer)
메시지(Message)
운영도구
MOM을 이용해서 P2P나 pub/sub 방식으로 메시지를 전달하고 메시지를 전달 받기 위한 API는 JM
S에서 제공하지만 MOM 자체를 관리하기 위한 방법은 JMS에서 제공하지 않는다. 그렇기 때문에 MOM을 운영하려면 MOM에서 제공하는 운영도구를 사용해야 한다.
웹로직 서버는 MOM을 포함한다고 했는데, 포함된 MOM을 사용하려면 웹로직 서버에서 제공하는 기능을 이용해야 한다. MOM을 운영한다는 것은 목적지(destination)를 설정하기 위해서다
목적지라는 것은 P2P나 pub/sub 방식으로 메시지를 주고 받을 때 사용하기 위한 저장 공간이라고 생각하면 된다.
커넥션 팩토리
커넥션과 관련된 정보를 통해서 커넥션을 생성할 수 있는 인터페이스를 말한다.
클라이언트는 JNDI를 이용하여 커넥션 팩토리(Connection Factory)를 검색한 후 JMS 커넥션을 만들게 되는데, P2P 방식일 경우에는 javax.jms.QueueConnectionFactory를 사용하며, pub/sub 방식일 경우에는 javax.jms.TopicConnectionFactory 를 사용한다.
웹로직 서버는 weblogic.jms.ConnectionFactory 이라는 이름으로 커넥션 팩토리를 제공하기 때문에, 원하는 형태로 형식을 변환하여 사용해야 한다.
목적지
웹로직 콘솔에서 운영도구를 이용해서 목적지를 생성하고 JNDI에 이름을 등록하게 된다.
그러면 메시지를 MOM 에게 전송하면 목적지에 메시지가 전달된다.
커넥션
커넥션은 JMS 서비스 제공자와 클라이언트 간의 TCP/IP 커넥션을 의미하며, 세션을 생성하기 위해 사용된다.
커넥션을 생성하려면 커넥션 팩토리에 있는 createQueueConnection() 이나 createTopicConnection() 메소드를 호출해야 한다.
처음 커넥션이 생성되면 정지모드에 있으며, 정지 모드일 경우에는 메시지를 전달할 수만 있고 받을 수는 없다. 정지 모드에서 시작모드로 바꾸려면 Connection의 start()메소드를 사용하고, 반대로 다시 정지하려면 stop()메소드를 이용한다.
그리고 커넥션의 사용이 끝났다면 반드시 close()메소드를 호출해야 한다
세션
세션은 클라이언트와 JMS서버 간에 메시지를 생성하고 소비하기 위한 단일 스레드 환경이다.
P2P방식에서는 javax.jms.QueueSession을 pub/sub방식에서는 javax.jms.TopicSession을 사용한다.
메시지 생산자
클라이언트에서 메시지를 JMS서버에 전달하려면 메시지 생산자(Message Producer)을 이용해야 한다.
메시지 생산자는 세션을 통해서 만들어 질 수 있다. P2P 방식일 경우에는 QueueSender를, pub/sub 방식일 경우에는 TopicPublisher를 통해서 생성한다.
이렇게 생산된 메시지 생산자를 이용해서, P2P방식일 경우에는 QueueSender에 포함된 send()메소드를 통해서, pub/sub 방식을 경우에는 TopicPublisher에 있는 publish()메소드를 이용해서 메시지를 전달 할 수 있다.
메시지 소비자
클라이언트는 JMS 서버로부터 메시지를 받아들이기 위해서 메시지 소비자(Message Consumer)를 이용해야 한다.
메시지 소비자는 생산자와 마찬가지로 세션을 통해서 만들어질 수 있다. P2P방식을 경우에는 QueueReceiver를, pub/sub방식일 경우에는 TopicSubscriber를 통해서 생성한다.
이렇게 생성된 메시지 소비자를 이용해서 메시지를 받아들일 수 있는데, 두 가지 모두 receive()메소드를 이용해서 받아들인다.
메시지를 받아들이려면 반드시 커넥션을 start()한 상태이어야 하며, pub/sub 방식일 경우에는 비동기식으로 받아들이기 위해서 MessageListener 인터페이스를 구현한 후 TopicSubscriber에 있는
setMessageListener()에 등록하면 된다.
메시지
메시지는 메시지 생산자와 소비자 간에 교환되는 데이터를 말한다.
메시지는 헤더(header), 특성(property), 몸체(body)로 구성되어 있으며 어떠한 데이터라도 몸체에 담겨 전송할 수 있다.
메시지의 종류는 다음과 같다.
메시지 |
설명 |
TextMessage |
문자열 데이터 |
MapMessage |
이름과 값으로 구성된 데이터,이름은 String, 내용은 자바 기본형 |
BytesMessage |
바이트 스트림 데이터 |
StreamMessage |
자바 기본형 데이터들에 대한 스트림 |
ObjectMessage |
자바 직렬화 객체 |
Message |
TextMessage,MapMessage,BytesMessage,StreamMessage,ObjectMessage의 상위 인터페이스로 몸체가 없다. |
P2P 방식의 메시징 서비스 예제
P2P방식의 JMS 예제 프로그램 테스트
순서
1. 웹로직 콘솔을 이용해서 사용할 목적지를 생성한다.
2. 커넥션,세션,메시지 생산자, 메시지 객체를 이용한 메시지 전송 프로그램을 작성한다.
3. 메시지 전송 프로그램을 여러 번 실행한다.
4. 커넥션,세션,메시지 소비자, 메시지 객체를 이용해서 MOM 의 목적지에 저장된 메시지를 읽어 들여 출력하는 프로그램을 작성한다.
5. 메시지를 읽어 들이는 프로그램을 실행해서 저장된 내용을 읽어서 출력하는지 확인한다.
목적지 생성
1. 웹로직 콘솔에 로그인한 후 좌측 메뉴에서 Services -> JMS ->Store 을 선택한 후 우측 메뉴에서
Configure a new JMS File Store 를 클릭한다.
JMS 서버는 메시지를 저장할 공간이 필요한데, 저장할 공간으로 파일시스템을 이용하는 것이다.
2. mydomain 디렉토리 아래에 파일 스토어가 사용할 디렉토리를 생성한다.
여기서는 myjmsfilestore 이라는 디렉토리를 만든다.
3. 파일 스토어에 대한 환경을 설정한다.
디렉토리명 : myjmsfilestore
파일스토어명: MyJMSFileStore
나머지는 기본값으로 하고 create 버튼을 클릭한다.
4. Apply 버튼을 클릭한다.
5. 파일 스토어를 생성했다면 해당 파일 스토어를 사용하는 새로운 JMS 서버에 대한 환경을 설정해야 한다.
좌측의 항목 중 Services ->JMS ->Servers 항목을 선택한 후 우측메뉴의 Configure a new JMS Server 항목을 클릭한다.
6. JMS 서버 설정화면에서
서버명 : MyJMSFileStore
나머지는 기본값으로 나두고 create 버튼을 클릭한다.
7. JMS 서버에 대한 환경 설정이 끝나면 Target and Deploy 탭에서 Target 을 myserver로 지정한 후
Apply 버튼을 클릭한다.
8. 서버에 대한 설정이 끝나면 목적지를 생성해야 한다. Services ->JMS->Servers->Destinations 항목을 선택한다.
9. 우측메뉴에서 Configure a new JMS Queue 를 클릭한다.
10. JMS Queue 에 대한 설정 화면이 나오면
Name : MyJMSQueue
JNDI Name : jmsqueue
로 지정한다.
11. 새로운 JMS 큐에 대한 설정이 끝나면 좌측메뉴에서 MyJMSQueue 라는 이름의 JMS 큐가 생성된 것을 확인 할 수 있다.
새로운 환경을 적용하기 위해서 웹로직 서버를 재시작 한다.
메시지 전송 프로그램 작성
JMS서버로 전송하기 위한 MessageQueueSender.java 파일을 작성한다.
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageQueueSender {
public static void main(String args[]) {
if(args.length != 1){
System.out.println("사용법 : java MessageQueueSender 전송할 메시지");
System.exit(0);
}
try {
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(h);
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Queue queue = (Queue)ctx.lookup("jmsqueue");
QueueConnection con = factory.createQueueConnection();
QueueSession session = con.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
QueueSender qsender = session.createSender(queue);
TextMessage message = session.createTextMessage();
message.setText(args[0]);
qsender.send(message);
qsender.send(session.createMessage());
con.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
메시지 출력 프로그램 작성
JMS 서버로부터 메시지를 전달받기 위한 MessageQueueReceiver.java 파일을 작성한다.
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageQueueReceiver {
public static void main(String args[]){
try{
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL,"t3://localhost:7001");
Context ctx = new InitialContext(h);
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Queue queue = (Queue)ctx.lookup("jmsqueue");
QueueConnection con = factory.createQueueConnection();
QueueSession session = con.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
QueueReceiver qreceiver = session.createReceiver(queue);
con.start();
while(true){
Message msg = qreceiver.receive(1);
if(msg != null){
if(msg instanceof TextMessage) {
TextMessage tmpMsg = (TextMessage)msg;
System.out.println("읽어온 메시지: " + tmpMsg.getText());
}
}else
break;
}
con.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
프로그램 실행과 테스트
MessageQueueSender를 여러 번 실행하고 난 후, MessageQueueReceiver 를 실행한다.
MessageQueueReceiver가 MOM에 저장된 메시지를 출력하는지 확인한다.
pub/sub 방식의 메시징 서비스 예제
pub/sub 방식의 JMS 예제 프로그램의 작성 순서
1. 웹로직 콘솔을 이용해서 사용할 목적지 생성
2. 커넥션, 세션, 토픽 구독자, 메시지 객체를 이용해서 지정한 목적지로부터 메시지를 읽어오는 프로그램 작성
3. 메시지를 읽어 오기 위한 프로그램 2개 이상 실행
4. 커넥션, 세션, 토픽 발행자, 메시지 객체를 이용해서 MOM 의 목적지에 메시지를 발행하는 프로그램 작성
5. 메시지를 전송(발행)하기 위한 프로그램 실행
6. 메시지를 읽어오기 위해서 대기하고 있던 프로그램 2개 이상이 발행된 메시지를 읽어 출력하는지 확인
목적지 생성
1. pub/sub 방식을 이용하려면 먼저 웹로직 콘솔에서 토픽에 대한 목적지를 생성해야 한다.
MyJMSServer 아래의 Destinations 메뉴를 선택한 후 Configure a new JMS Topic 을 클릭한다.
2. JMS 토픽 목적지에 대한 설정을 한다. 이름은 MyJMSTopic, JNDI 명은 jmstopic 으로 지정한 후 create 버튼을 클릭한다.
메시지 전송 프로그램 작성
JMS서버로부터 비동기적으로 메시지를 읽어 들이는 MessageTopicSubscriber.java 파일을 작성한다.
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageTopicSubscriber {
public static void main(String args[]){
try{
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL,"t3://localhost:7001");
Context ctx = new InitialContext(h);
TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Topic topic = (Topic)ctx.lookup("jmstopic");
TopicConnection con = factory.createTopicConnection();
TopicSession session = con.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber = session.createSubscriber(topic);
subscriber.setMessageListener(new MessageListener(){
public void onMessage(Message message){
try{
if(message instanceof TextMessage){
TextMessage m = (TextMessage)message;
System.out.println(m.getText());
}
}catch(Exception e){
System.out.println(e.toString());
}
}
});
con.start();
while(true){
char c = (char)System.in.read();
if(c == 'q')
break;
}
con.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
메시지 출력 프로그램 작성
JMS 서버에게 메시지를 pub/sub 방식으로 전달하기 위한 MessageTopicPublisher.java 파일을 작성한다.
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageTopicPublisher {
public static void main(String args[]) {
if(args.length!=1){
System.out.println("사용법 : java MessageTopicPublisher 전송할 메시지");
System.exit(0);
}
try{
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL,"t3://localhost:7001");
Context ctx = new InitialContext(h);
TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Topic topic = (Topic)ctx.lookup("jmstopic");
TopicConnection con = factory.createTopicConnection();
TopicSession session = con.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
TopicPublisher publisher = session.createPublisher(topic);
TextMessage message = session.createTextMessage();
message.setText(args[0]);
publisher.publish(message);
con.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
프로그램 실행과 테스트
창을 2개 이상 열어서 각각 MessageTopicSubscriber를 실행한다.
새창을 열어서 MessageTopicPublisher 를 실행한 후 MessageTopicSubscriber 실행창에서 메시지를 출력하는지 확인한다.
[출처] [weblogic]4.JMS(Java Message Service)|작성자 피쉬
파란실버라이트
To remember the time when I started learning Silver Light!