JMS(Java Message Service)는 자바 애플리케이션 간 메시지 기반 통신을 가능하게 하는 Java EE 표준 API입니다. 애플리케이션은 JMS를 통해 비동기적이고 신뢰성 있는 메시징 시스템을 구축할 수 있습니다. JMS의 주요 구성 요소와 각 요소의 기능을 자세히 살펴보겠습니다.


1. JMS의 주요 구성 요소

1-1. 어드민 오브젝트

JMS에서 두 가지 주요 어드민 오브젝트는 연결 팩토리(Connection Factory)대상지(Destination)입니다. 이 오브젝트들은 일반적으로 애플리케이션 코드로 생성하지 않고 JNDI(Java Naming and Directory Interface)를 통해 관리하고 호출합니다. 이는 설정을 중앙에서 관리하고, 클라이언트의 코드를 단순화하며, 다양한 JMS 구현 간의 이식성을 높이기 위함입니다.

  1. 연결 팩토리 (Connection Factory):
    • JMS 제공자와의 연결을 설정하는 데 사용됩니다. ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory가 있으며, 각각 메시지 큐, 토픽에 연결하는 팩토리를 나타냅니다.
    • JNDI로부터 연결 팩토리를 가져와 설정을 쉽게 구성할 수 있습니다.
  2. 대상지 (Destination):
    • 대상지는 메시지를 보내고 받을 때 사용되며, PTP 모델에서는 큐(Queue), Pub/Sub 모델에서는 토픽(Topic)이라 불립니다.
    • 큐는 한 명의 소비자만 메시지를 받을 수 있는 반면, 토픽은 여러 소비자가 동시에 메시지를 받을 수 있습니다.
    • 대상지 또한 JNDI에 의해 관리되며, 애플리케이션에서 @Resource 어노테이션을 통해 참조할 수 있습니다.

1-2. 연결 (Connection)

  • JMS 제공자와 클라이언트 간의 실제 연결을 의미하며, 주로 TCP/IP 소켓 연결을 사용하여 메시징 인프라와 통신합니다.
  • ConnectionFactory를 통해 Connection 객체를 생성하고 connection.start() 메서드를 호출하여 메시지를 주고받기 시작합니다.
  • 애플리케이션이 종료될 때는 connection.close()를 호출하여 리소스를 정리합니다.

1-3. 세션 (Session)

  • 세션은 클라이언트의 단일 스레드 문맥으로서, 메시지의 전송과 수신을 관리합니다. 주로 Session 객체를 통해 메시지를 생성하고, 프로듀서 및 컨슈머를 생성하며, 트랜잭션 처리를 수행합니다.
  • 세션은 트랜잭션 모드인증 모드를 설정할 수 있습니다.
    • 트랜잭션 모드: 세션을 트랜잭션으로 설정하여 다수의 메시지를 하나의 트랜잭션으로 묶을 수 있습니다.
    • 인증 모드: AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE 등 다양한 인증 모드를 통해 메시지가 성공적으로 소비되었는지 확인합니다.

1-4. 메시지 프로듀서 (Message Producer)

  • 메시지 프로듀서는 특정 대상지에 메시지를 전송하는 객체입니다. Session을 통해 생성하며, MessageProducer.send() 메서드를 통해 메시지를 전송합니다.
  • 특정 대상지를 지정하지 않고 null을 통해 익명 프로듀서를 생성할 수 있으며, 이 경우 메시지를 전송할 때 대상지를 지정해야 합니다.

1-5. 메시지 컨슈머 (Message Consumer)

  • 메시지 컨슈머는 특정 대상지로부터 메시지를 수신하는 객체입니다. 컨슈머는 메시지를 동기적(receive 메서드) 또는 비동기적으로 수신할 수 있습니다.
  • 동기적 수신: receive() 메서드를 사용하여 메시지가 도착할 때까지 대기합니다.
  • 비동기적 수신: MessageListener를 설정하여 메시지가 도착할 때 콜백 메서드 onMessage()를 호출합니다.
  • 특정 조건에 맞는 메시지만 선택적으로 수신하기 위해 메시지 선택기를 사용할 수 있습니다. SQL92 표현식으로 특정 조건을 설정해 필터링할 수 있습니다.

2. JMS 메시지 구조

JMS 메시지는 다음 세 가지 주요 구성 요소로 이루어져 있습니다.

  1. 메시지 헤더:
    • JMSDestination: 메시지가 도착할 대상(큐 또는 토픽)을 나타냅니다.
    • JMSMessageID: 메시지의 고유 식별자입니다.
    • JMSTimestamp: 메시지가 전송된 시간입니다.
    • JMSPriority: 메시지의 우선순위 수준입니다.
    • JMSDeliveryMode: 지속성 모드입니다. 지속성 메시지는 시스템이 재부팅되어도 손실되지 않습니다.
  2. 메시지 속성 (Properties):
    • 추가적인 정보나 메시지 선택기를 통해 메시지를 필터링하기 위한 값을 저장할 수 있습니다.
  3. 메시지 본문 (Body):
    • 메시지 본문은 여러 형식을 지원하며, 다음의 형식들이 있습니다.
      • TextMessage: 단순 텍스트 데이터 (예: XML)
      • MapMessage: 이름-값 쌍 형태
      • BytesMessage: 바이트 스트림으로 이루어진 데이터
      • StreamMessage: Java의 원시 타입 스트림
      • ObjectMessage: Java 객체

3. 메시지 전송과 수신 예시

// 메시지 프로듀서 생성 및 메시지 전송
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("Hello JMS!");
producer.send(message);

// 메시지 컨슈머 생성 및 메시지 수신 (동기 방식)
MessageConsumer consumer = session.createConsumer(destination);
Message receivedMessage = consumer.receive();
if (receivedMessage instanceof TextMessage) {
    TextMessage textMessage = (TextMessage) receivedMessage;
    System.out.println("Received: " + textMessage.getText());
}

// 비동기 방식 메시지 수신
consumer.setMessageListener(new MessageListener() {
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            System.out.println("Received asynchronously: " + textMessage.getText());
        }
    }
});

4. JMS 트랜잭션 및 예외 처리

트랜잭션 관리

JMS는 트랜잭션 기능을 제공하여 다수의 메시지를 한 번에 처리할 수 있습니다. 트랜잭션을 사용하면 여러 메시지를 하나의 단위로 묶어 성공 시 한 번에 커밋하고, 실패 시 롤백하여 안정성을 높일 수 있습니다.

예외 처리

JMS의 모든 예외는 JMSException을 상속받아 발생하며, 주요 예외로는 다음이 있습니다.

  • InvalidDestinationException: 잘못된 대상지 사용 시 발생
  • JMSException: 기본 예외 클래스로, 메시지 전송 실패 등 다양한 경우 발생

5. JMS의 메시지 모델

  1. PTP(Point-to-Point) 모델:
    • 하나의 발신자가 하나의 수신자에게 메시지를 보냅니다.
    • 각 메시지는 큐에 저장되고, 한 번만 소비되며, 특정 수신자만 큐로부터 메시지를 소비할 수 있습니다.
  2. Pub/Sub(Publish/Subscribe) 모델:
    • 하나의 발신자가 여러 수신자에게 동시에 메시지를 보냅니다.
    • 수신자는 원하는 주제(토픽)에 구독하며, 토픽에 게시된 메시지를 모두 받을 수 있습니다.
    • 지속적 구독을 설정하여 연결되지 않은 상태에서 메시지를 놓치지 않도록 할 수 있습니다.

6. JMS의 활용 및 특징

  • 높은 이식성: JNDI를 통해 특정 벤더와 독립적으로 애플리케이션을 작성할 수 있습니다.
  • 비동기 메시징: MessageListener를 사용하여 비동기적으로 메시지를 수신할 수 있습니다.
  • 확장성: 다양한 메시지 유형과 프로토콜을 사용하여 애플리케이션을 확장할 수 있습니다.

JMS는 이와 같은 특징으로 금융, 물류, 전자상거래 등 다양한 분야에서 안정적이고 확장 가능한 메시지 기반 시스템을 구축하는 데 사용됩니다.

'Java' 카테고리의 다른 글

Java의 Executor 인터페이스 (스레드풀)  (0) 2024.12.13
Stream  (0) 2024.11.05
jar, war 설명과 차이  (0) 2024.10.09
Shallow copy와 Deep copy  (0) 2024.09.19
어그리게이션(Aggregation)과 컴포지션(Composition)  (0) 2024.08.21

+ Recent posts