34.1 JMS by sh

JMS

  • 메시지 큐를 지원하는 J2EE의 메시지 처리 API

    • 자바 전용이라 AMQP는 지원하지 않는다.

메시지 큐

  • MOM을 구현한 시스템 (웹 서버의 성능을 고려한 비동기 메시지 처리 방식)

    • MOM (= Message Oriented Middleware) : 분산 시스템 간 메시지를 주고 받는 기능을 지원하는 소프트웨어나 하드웨어 인프라

JMS 주요 개념

  • Message Broker : 목적지에 안전하게 메시지를 건네주는 중개자 역할

  • Destination : 목적지에 배달될 2가지 메시지 모델 QUEUE, TOPIC

    • Queue : Point to Point (Consumer는 메시지를 받기 위해 경쟁)

    • Topic : Publish to Subscribe

javax.jms.ConnectionFactory 인터페이스는 JMS 브로커와 상호 작용하기 위한 javax.jms.Connection을 만드는 표준 방법을 제공합니다. Spring은 JMS와 연동하기 위해 ConnectionFactory가 필요하지만 일반적으로 직접 사용하지 않아도 되며 상위 수준의 메시징 추상화에 의존 할 수있습니다. (자세한 내용은 Spring Framework 참조 문서의 therelevant section을 참조하십시오.) Spring Boot는 또한 메시지를 보내고 받기 위해 필요한 인프라를 자동으로 구성합니다.

34.1.1 ActiveMQ 지원

ActiveMQ

  • 클라이언트 간 메시지를 송수신 할 수 있는 오픈 소스 브로커 (JMS 서버), MOM(메시지 지향 미들웨어)이다.

메시지 처리 구조?

기본적으로 메시지를 생산하는 Producer, activeMQ Broker(Server), 메시지를 소비하는 Consumer로 구성되어 있다.

  • Queue 모델의 경우 메시지를 받는 Consumer가 다수일 때 연결된 순서로 메시지 제공됨

    • 생성자로부터 단일 사용자에게 전달된다.

  • Topic 모델의 경우 메시지를 받는 Consumer가 다수일 때 모두에게 메시지 제공됨

    • 단일 생성자가 사용자의 수 제한 없이 메시지를 전달한다.

classpath에서 ActiveMQ를 사용할 수 있으면, Spring Boot는 ConnectionFactory를 설정할 수도 있습니다. 브로커가 있으면 내장 브로커가 자동으로 시작되고 구성됩니다 (구성을 통해 브로커 URL을 지정하지 않은 경우).

spring-boot-starter-activemq를 사용하면 JMS와 통합할 Spring 인프라와 마찬가지로 ActiveMQ 인스턴스를 연결하거나 포함시키는 데 필요한 종속성이 제공됩니다.

ActiveMQ 구성은 spring.activemq.*의 외부 구성 등록 정보에 의해 제어됩니다. 예를 들어 다음 섹션을 application.properties로 선언 할 수 있습니다.

spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret

기본적으로 CachingConnectionFactory는 고유한 ConnectionFactory를 외부 구성 속성들에 의해 spring.jms.*로 제어 할 수있는 적절한 설정으로 래핑합니다.

spring.jms.cache.session-cache-size=5

네이티브 풀링을 사용하려면 다음 예제와 같이 org.messaginghub:pooled-jms에 종속성을 추가하고 JmsPoolConnectionFactory를 구성하여 그렇게 할 수 있습니다

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50

지원되는 옵션에 대해서는 ActiveMQProperties를 참조하십시오. 고급 사용자 정의를 위해 ActiveMQConnectionFactoryCustomizer를 구현하는 임의의 수의 Bean을 등록 할 수도 있습니다.

기본적으로 ActiveMQ는 목적지가 아직 존재하지 않는 경우 목적지를 작성하여 목적지가 제공된 이름에 대해 해석되도록합니다.

34.1.2 Artemis 지원

Spring Boot는 클래스 패스에서 Artemis를 사용할 수 있음을 감지하면 ConnectionFactory를 자동으로 구성 할 수 있습니다. 브로커가 있으면 내장 된 브로커가 자동으로 시작되고 구성됩니다 (mode 등록 정보가 명시적으로 설정되어 있지 않은 경우). 지원되는 모드는 embedded(내장된 브로커가 필요하며 브로커를 클래스 경로에서 사용할 수 없는 경우 오류가 발생하도록 명시하는)native(netty전송 프로토콜을 사용하여 브로커에 연결하는)입니다. 후자가 구성되면 스프링 부트는 기본 설정으로 로컬 시스템에서 실행 중인 브로커에 연결하는 ConnectionFactory를 구성합니다.

spring-boot-starter-artemis를 사용하면 JMS와 통합 할 Spring 인프라뿐만 아니라 기존 Artemis 인스턴스에 연결하는 데 필요한 종속성이 제공됩니다. 애플리케이션에 org.apache.activemq:artemis-jms-server를 추가하면 임베디드 모드를 사용할 수 있습니다.

Artemis 구성은 spring.artemis.*의 외부 구성 등록 정보에 의해 제어됩니다. 예를 들어 다음 섹션을 application.properties로 선언 할 수 있습니다.

spring.artemis.mode=native
spring.artemis.host=192.168.1.210
spring.artemis.port=9876
spring.artemis.user=admin
spring.artemis.password=secret

브로커를 임베드 할 때 지속성을 활성화 할 것인지 선택할 수 있으며 사용 가능하게 할 대상을 나열 할 수 있습니다. 이것들은 쉼표로 구분 된 목록으로 지정하여 기본 옵션으로 만들거나 org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration 또는 org.apache.activemq.artemis.jms.server.config.TopicConfiguration타입의 bean을 정의 할 수 있습니다. 이것들은 각각 고급 큐 및 주제 구성 각각에 대해 설명합니다.

기본적으로 CachingConnectionFactory는 고유 한 ConnectionFactory를 외부 구성 등록 정보 인 spring.jms.*로 제어 할 수있는 적절한 설정으로 래핑합니다.

spring.jms.cache.session-cache-size=5

네이티브 풀링을 사용하려면 다음 예제와 같이 org.messaginghub:pooled-jms에 종속성을 추가하고 JmsPoolConnectionFactory를 구성하여 그렇게 할 수 있습니다.

spring.artemis.pool.enabled=true
spring.artemis.pool.max-connections=50

지원되는 옵션에 대해서는 ArtemisProperties를 참조하십시오.

JNDI 조회가 필요 없으며 대상은 Artemis 구성의 name속성 또는 구성을 통해 제공된 이름을 사용하여 이름에 대해 확인됩니다.

34.1.3 JNDI ConnectionFactory 사용

응용 프로그램 서버에서 응용 프로그램을 실행하는 경우 Spring Boot는 JNDI를 사용하여 JMS ConnectionFactory를 찾으려고 시도합니다. 기본적으로 java:/JmsXAjava:/XAConnectionFactory 위치가 검사됩니다. 다음 예제와 같이 대체 위치를 지정해야하는 경우 spring.jms.jndi-name 등록 정보를 사용할 수 있습니다.

spring.jms.jndi-name=java:/MyConnectionFactory

JMS 프로그래밍 모델에서 사용되는 2가지 객체

1. 연결 팩토리 객체 : 공급자가 메시지 전달 시 사용하는 프로토콜 및 메커니즘에 따라 동작이 달라지는 연결을 작성하는 데 사용

2. 대상 객체 : 브로커의 물리적 대상의 이름을 지정하는 데 사용. 메시지 서버에 있는 물리적 대상의 특정 이름 지정 규약 및 기능에 따라 다르다.

  • JMS 관리 대상 객체

    • 관리자가 작성 및 구성하고 JNDI 이름 영역(객체 저장소)에서 저장하며 클라이언트가 표준 JNDI 조회 코드를 통해 액세스한다. (공급자 별 객체 조회, 참조할 때 논리적 이름 사용)

34.1.4 메시지 전송

Spring의 JmsTemplate은 자동으로 구성되어 있으므로 다음 예제와 같이 직접 bean에 autowire 할 수 있습니다.

JmsTemplate

  • 스프링에서 JMS 메시징을 사용하는 핵심 컴포넌트 (동기적으로 메시지를 받거나 보내는 데 사용)

https://starplatina.tistory.com/entry/JMS-2

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final JmsTemplate jmsTemplate;

	@Autowired
	public MyBean(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	// ...

}

JmsMessagingTemplate도 비슷한 방식으로 주입 할 수 있습니다. DestinationResolver또는 MessageConverterbean이 정의되면 자동 구성된 JmsTemplate에 자동으로 연관됩니다.

34.1.5 메시지 수신

JMS 인프라가 존재할 때 모든 Bean에 @JmsListener주석을 달아 리스너 엔드 포인트를 작성할 수 있습니다. JmsListenerContainerFactory가 정의되어 있지 않은 경우, 디폴트의 JmsListenerContainerFactory가 자동적으로 설정됩니다. DestinationResolver또는 MessageConverterbean이 정의되면, 디폴트 팩토리에 자동으로 연관됩니다.

기본적으로 기본 팩토리는 트랜잭션입니다. JtaTransactionManager가있는 인프라에서 실행하면 기본적으로 리스너 컨테이너에 연결됩니다. 그렇지 않으면 sessionTransacted플래그가 사용됩니다. 후자의 경우 리스너 메소드 (또는 그 대리자)에 @Transactional을 추가하여 로컬 데이터 저장소 트랜잭션을 수신 메시지 처리에 연결할 수 있습니다. 이렇게하면 로컬 트랜잭션이 완료되면 수신 메시지가 확인됩니다. 여기에는 동일한 JMS 세션에서 수행 된 응답 메시지를 보내는 작업도 포함됩니다.

JMS 작업을 하나의 트랜잭션 안에서 동작하게 하려면 서버가 제공하는 트랜잭션 매니저를 JTA를 통해 사용해야 함.

다음 구성 요소는 someQueue대상에 리스너 끝점을 만듭니다.

@Component
public class MyBean {

	@JmsListener(destination = "someQueue")
	public void processMessage(String content) {
		// ...
	}

}

자세한 내용은 the Javadoc of @EnableJms을 참조하십시오.

더 많은 JmsListenerContainerFactory인스턴스를 생성해야하거나 기본값을 덮어 쓰려면 Spring Boot는 자동 구성 된 것과 동일한 설정으로 DefaultJmsListenerContainerFactory를 초기화하는 데 사용할 수있는 aDefaultJmsListenerContainerFactoryConfigurer를 제공합니다.

예를 들어, 다음 예제는 특정 MessageConverter를 사용하는 다른 팩토리를 노출합니다.

@Configuration
static class JmsConfiguration {

	@Bean
	public DefaultJmsListenerContainerFactory myFactory(
			DefaultJmsListenerContainerFactoryConfigurer configurer) {
		DefaultJmsListenerContainerFactory factory =
				new DefaultJmsListenerContainerFactory();
		configurer.configure(factory, connectionFactory());
		factory.setMessageConverter(myMessageConverter());
		return factory;
	}

}

다음과 같이 @JmsListener-annotated 메서드에서 팩토리를 사용할 수 있습니다.

@Component
public class MyBean {

	@JmsListener(destination = "someQueue", containerFactory="myFactory")
	public void processMessage(String content) {
		// ...
	}

}

Last updated