Spring/3.x

JMS 개념 및 Spring에서 지원하는 JMS, MDP

EnterKey 2016. 2. 22. 14:11
반응형

Table of Contents

예제

아래 예제에서 주가 정보를 주고 받는 클라이언트 애플리케이션을 살펴 보자.

  1. 메세지를 보내고 받기 위한 선행작업
    • Getting a ConnectionFactory
      import javax.naming.*;
      import javax.jms.*;
      ConnectionFactory connectionFactory;
      Context messaging = new InitialContext();
      connectionFactory = (ConnectionFactory)messaging.lookup("ConnectionFactory");
      
    • Getting a Destination
      Queue stockQueue;
      stockQueue = (Queue)messaging.lookup("StockSource");
      
    • Creating a Connection
      Connection connection;
      connection = ConnectionFactory.createConnection();
      
    • Creating a Session
      Session session;
      
      /* Session is not transacted,
       * uses AUTO_ACKNOWLEDGE for message
       * acknowledgement
       */
      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      
    • Creating a MessageProducer
      MessageProducer sender;
      
      /* Value in stockQueue previously looked up in the JNDI
       * createProducer takes a Destination
       */
      sender = session.createProducer(stockQueue);
      
    • Creating a MessageConsumer
      MessageConsumer receiver;
      
      /* Value in stockQueue previously looked up in the JNDI
       * createConsumer takes a Destination
       */
      receiver = session.createConsumer(stockQueue);
      
    • Starting Message Delivery
      connection.start();
      
    • Using a TextMessage
      String stockData; /* Stock information as a string */
      TextMessage message;
      
      /* Set the message's text to be the stockData string */
      message = session.createTextMessage();
      message.setText(stockData);
      
  2. 메세지 주고 받기
    • 메세지 보내기
      /* Send the message */
      sender.send(message);
      
    • 메세지를 동기적으로 받기
      TextMessage stockMessage;
      stockMessage = (TextMessage)receiver.receive();
      
      TextMessage stockMessage;
      
      /* Wait 4 seconds for a message */
      TextMessage = (TextMessage)receiver.receive(4000);
      
    • TextMessage에서 정보 추출하기
      String newStockData; /* Stock information as a string */
      newStockData = message.getText();
      
  3. 그밖의 메세징 관련하여 알아 둘 사항들
    • 메세지를 비동기적으로 받기
      import javax.jms.*;
      public class StockListener implements MessageListener
      {
          public void onMessage(Message message) {
              /* Unpack and handle the messages received */
              ...
          }
      }
      
      StockListener myListener = new StockListener();
      
      /* Receiver is MessageConsumer object */
      receiver.setMessageListener(myListener);
      
      public void onMessage(Message message)
      {
          String newStockData;
          /* Unpack and handle the messages received */
          newStockData = message.getText();
          if(...)
          {
              /* Logic related to the data */
          }
      }
      
    • Message Selection 사용하기
      String stockData; /* Stock information as a String */
      TextMessage message;
      
      /* Set the message's text to be the stockData string */
      message = session.createTextMessage();
      message.setText(stockData);
      
      /* Set the message property 'StockSector' */
      message.setStringProperty("StockSector", "Technology");
      
      String selector;
      selector = new String("(StockSector = 'Technology')");
      
      MessageConsumer receiver;
      receiver = session.createConsumer(stockQueue, selector);
      
    • Durable Subcription 사용하기
      import javax.naming.*;
      import javax.jms.*;
      
      /* Look up connection factory */
      ConnectionFactory connectionFactory;
      Context messaging = new InitialContext();
      connectionFactory = (ConnectionFactory) Messaging.lookup("ConnectionFactory")
      
      /* Look up destination */
      Topic newsFeedTopic;
      newsFeedTopic = messaging.lookup("BreakingNews");
      
      /* Create connection and session */
      Connection connection;
      Session session;
      connection = ConnectionFactory.createConnection();
      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      
      session.createDurableSubscriber(newsFeedTopic,"mySubscription");
      
      /* Reconnect to a durable subscription */
      session.createDurableSubscriber(newsFeedTopic, "mySubscription");
      
  4. JMS 메세지 타입
    • TextMessage
      • 생성하기
        String stockData; /* Stock information as a string */
        TextMessage message;
        message = session.createTextMessage();
        
        /* Set the stockData string to the message body */
        message.setText(stockData);
        
      • 정보 추출하기
        String stockInfo; /* String to hold stock info */
        stockInfo = message.getText();
        
    • BytesMessage
      • 생성하기
        byte[] stockData; /* Stock information as a byte array */
        BytesMessage message;
        message = session.createBytesMessage();
        message.writeBytes(stockData);
        
      • 정보 추출하기
        byte[] stockInfo; /* Byte array to hold stock information */
        int length;
        length = message.readBytes(stockInfo);
        
    • MapMessage
      • 생성하기
        String stockName; /* Name of the stock */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time the stock quote was updated */
        double stockDiff; /* the +/- change in the stock quote*/
        String stockInfo; /* Other information on this stock */
        MapMessage message;
        
        message = session.createMapMessage();
        
        message.setString("Name", "SUNW");
        message.setDouble("Value", stockValue);
        message.setLong("Time", stockTime);
        message.setDouble("Diff", stockDiff);
        message.setString("Info", "Recent server announcement causes market interest");
        
      • 정보 추출하기
        String stockName; /*Name of the stock */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time of the stock update */
        double stockDiff; /* +/- change in the stock */
        String stockInfo; /* Information on this stock */
        
        stockName = message.getString("Name");
        stockDiff = message.getDouble("Diff");
        stockValue = message.getDouble("Value");
        stockTime = message.getLong("Time");
        
    • StreamMessage
      • 생성하기
        String stockName; /* Name of the stock */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time of the stock update */
        double stockDiff; /* +/- change in the stock quote */
        String stockInfo; /* Information on this stock*/
        StreamMessage message;
        
        /* Create message */
        message = session.createStreamMessage();
        
        /* Set data for message */
        message.writeString(stockName);
        message.writeDouble(stockValue);
        message.writeLong(stockTime);
        message.writeDouble(stockDiff);
        message.writeString(stockInfo);
        
      • 정보 추출하기
        String stockName; /* Name of the stock quote */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time of the stock update */
        double stockDiff; /* +/- change in the stock quote */
        String stockInfo; /* Information on this stock */
        
        stockName = message.readString();
        stockValue = message.readDouble();
        stockTime = message.readLong();
        stockDiff = message.readDouble();
        stockInfo = message.readString();
        
    • ObjectMessage
      • 생성하기
        String stockName; /* Name of the stock quote */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time of the stock update */
        double stockDiff; /* +/- change in the stock quote */
        String stockInfo; /* Information on this stock */
        
        /* Create a StockObject */
        StockObject stockObject = new StockObject();
        
        /* Establish the values for the StockObject */
        stockObject.setName(stockName);
        stockObject.setValue(stockValue);
        stockObject.setTime(stockTime);
        stockObject.setDiff(stockDiff);
        stockObject.setInfo(stockInfo);
        
        /* Create an ObjectMessage */
        ObjectMessage message;
        message = session.createObjectMessage();
        
        /* Set the body of the message to the StockObject */
        message.setObject(stockObject);
        
      • 정보 추출하기
        StockObject stockObject;
        /* Retrieve the StockObject from the message */
        stockObject = (StockObject)message.getObject();
        
        /* Extract data from the StockObject by using StockObject methods */
        String stockName; /* Name of the stock quote */
        double stockValue; /* Current value of the stock */
        long stockTime; /* Time of the stock update */
        double stockDiff; /* +/- change in the stock quote */
        String stockInfo; /* Information on this stock */
        
        stockName = stockObject.getName();
        stockValue = stockObject.getValue();
        stockTime = stockObject.getTime();
        stockDiff = stockObject.getDiff();
        stockInfo = stockObject.getInfo();
        

JMS Spec

  1. 소개
    • JMS는 자바 프로그램이 엔터프라이즈 메시징 시스템의 메세지를 생성, 보내기, 받기, 읽기 위한 공통의 방법을 제공한다.
    • 엔터프라이즈 메세징 상품(흔히 MOM(Message Oriented Middleware) 상품이라고 말한다.)은 intra-company operations을 통합하기 위한 주요 컴포넌트이다. 이런 상품들은 서로 떨어진 비즈니스 컴포넌트들을 reliable하면서도 flexible하게 엮어준다.
      자바 언어로 된 클라이언트들과 자바 언어의 미들 티어 서비스들은 이러한 메세징 시스템을 이용할 수 있어야 하는데, 이때 JMS가 이러한 시스템에 접근하기 위한 공통 방식을 정의하고 있는 것이다.
      JMS는 인터페이스 셑과 JMS 클라이언트가 엔터프라이즈 메시징 상품의 facilities에 접근하는 방식을 정의한 associated semantics를 가지고 있다.
    • 메세징은 peer-to-peer임으로 JMS의 모든 사용자는 일반적으로 클라이언트로 생각하면 된다. JMS 애플리케이션은 애플리케이션에서 정의한 메세지와 그것을 주고 받는 클라이언트 셑으로 구성된다. JMS를 구현하고 있는 상품들은 JMS 인터페이스를 구현한 provider를 제공한다.
      • 여기서 메세지란 (사람이 아닌)엔터프라이즈 애프리케이션 간의 비동기 커뮤니케이션을 말한다.
  2. 아키텍처
    • JMS application 구성요소
      • JMS Clients - These are the Java language programs that send and receive messages.
      • Non-JMS Clients - These are clients that use a message system's native client API instead of JMS. If the application predated the availability of JMS it is likely that it will include both JMS and non-JMS clients.
      • Messages - Each application defines a set of messages that are used to communicate information between its clients.
      • JMS Provider - This is a messaging system that implements JMS in addition to the other administrative and control functionality required of a fullfeatured messaging product.
      • Administered Objects - Administered objects are preconfigured JMS objects
        created by an administrator for the use of clients.
        #*There are two types of JMS administered objects:
      • ConnectionFactory - This is the object a client uses to create a connection
        with a provider.
      • Destination - This is the object a client uses to specify the destination of
        messages it is sending and the source of messages it receives.
    • Two Messaging Styles
      • JMS Point-to-Point Model - Queue
      • JMS Publish/Subscribe Model - Topic
    • JMS 오브젝트간 관계
      • ConnectionFactory - an administered object used by a client to create a Connection
      • Connection - an active connection to a JMS provider
      • Destination - an administered object that encapsulates the identity of a message destination
      • Session - a single-threaded context for sending and receiving messages
      • MessageProducer - an object created by a Session that is used for sending messages to a destination
      • MessageConsumer - an object created by a Session that is used for receiving messages sent to a destination
    • A typical JMS client executes the following JMS setup procedure:
      • Use JNDI to find a ConnectionFactory object
      • Use JNDI to find one or more Destination objects
      • Use the ConnectionFactory to create a JMS Connection with message delivery inhibited
      • Use the Connection to create one or more JMS Sessions
      • Use a Session and the Destinations to create the MessageProducers and MessageConsumers needed
      • Tell the Connection to start delivery of messages
        At this point a client has the basic JMS setup needed to produce and consume
        messages.
    • Multithreading
      • 세션에 대해 동시 접근을 막는 이유에는 두가지 이유가 있다.
        세션은 트랙잭션을 지원하는 엔티티인데, 멀티 스레드인 트랜잭션을 구현하는 것은 매우 어렵기 때문이다.
        세션은 비동기 메세지 소비를 지원하는데, JMS는 여러개의 메세지를 동시에 핸들링하는 걸 요구하지 않는다는 점이 중요하다.
        동시성이 요구된다면, 여러개의 세션을 만들어 처리하면 될 것이다.
  3. JMS Common Facilities

Spring Ref. Ch.19

ProSpring 책 정리

Spring In Action 책 정리

JMS Provider - ActiveMQ

참고자료

Pro Spring 책 p.467~486
Spring 레퍼런스 JMS 번역
Spring 레퍼런스 JMS
Asynchronous Messaging Made Easy With Spring JMS
Spring 2.0's JMS Improvements
Spring 2.0's JMS Improvements 번역
1-2-3 messaging with Spring JMS
J2EE Java Message Service (JMS)
JMS in WikipediA


출처: http://www.javajigi.net/pages/viewpage.action?pageId=5665

반응형