JMS(Java Message Service)는 자바 애플리케이션 간 메시지 기반 통신을 가능하게 하는 Java EE 표준 API입니다. 애플리케이션은 JMS를 통해 비동기적이고 신뢰성 있는 메시징 시스템을 구축할 수 있습니다. JMS의 주요 구성 요소와 각 요소의 기능을 자세히 살펴보겠습니다.
1. JMS의 주요 구성 요소
1-1. 어드민 오브젝트
JMS에서 두 가지 주요 어드민 오브젝트는 연결 팩토리(Connection Factory)와 대상지(Destination)입니다. 이 오브젝트들은 일반적으로 애플리케이션 코드로 생성하지 않고 JNDI(Java Naming and Directory Interface)를 통해 관리하고 호출합니다. 이는 설정을 중앙에서 관리하고, 클라이언트의 코드를 단순화하며, 다양한 JMS 구현 간의 이식성을 높이기 위함입니다.
- 연결 팩토리 (Connection Factory):
- JMS 제공자와의 연결을 설정하는 데 사용됩니다.
ConnectionFactory
,QueueConnectionFactory
,TopicConnectionFactory
가 있으며, 각각 메시지 큐, 토픽에 연결하는 팩토리를 나타냅니다. - JNDI로부터 연결 팩토리를 가져와 설정을 쉽게 구성할 수 있습니다.
- JMS 제공자와의 연결을 설정하는 데 사용됩니다.
- 대상지 (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 메시지는 다음 세 가지 주요 구성 요소로 이루어져 있습니다.
- 메시지 헤더:
- JMSDestination: 메시지가 도착할 대상(큐 또는 토픽)을 나타냅니다.
- JMSMessageID: 메시지의 고유 식별자입니다.
- JMSTimestamp: 메시지가 전송된 시간입니다.
- JMSPriority: 메시지의 우선순위 수준입니다.
- JMSDeliveryMode: 지속성 모드입니다. 지속성 메시지는 시스템이 재부팅되어도 손실되지 않습니다.
- 메시지 속성 (Properties):
- 추가적인 정보나 메시지 선택기를 통해 메시지를 필터링하기 위한 값을 저장할 수 있습니다.
- 메시지 본문 (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의 메시지 모델
- PTP(Point-to-Point) 모델:
- 하나의 발신자가 하나의 수신자에게 메시지를 보냅니다.
- 각 메시지는 큐에 저장되고, 한 번만 소비되며, 특정 수신자만 큐로부터 메시지를 소비할 수 있습니다.
- 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 |