34.2 AMQP by sh

AMQP (Advanced Message Queuing Protocol)는 메시지 중심 미들웨어를 위한 플랫폼 중립적인 유선 수준의 프로토콜입니다. Spring AMQP 프로젝트는 핵심 Spring 개념을 AMQP 기반 메시징 솔루션 개발에 적용합니다. Spring Boot는 spring-boot-starter-amqp "Starter"를 포함하여 RabbitMQ를 통해 AMQP를 사용하기위한 몇 가지 편의를 제공합니다.

MQ?

  • 프로그래밍에서 MQ는 프로세스 또는 프로그램 인스턴스가 데이터를 서로 교환할 때 사용하는 방법을 의미한다.

AMQP

  • MQ를 오픈 소스에 기반한 표준 프로토콜 (이 프로토콜을 구현한 MQ 제품들 중 하나가 RabbitMQ)

34.2.1 RabbitMQ 지원

RabbitMQ는 AMQP 프로토콜을 기반으로하는 가볍고, 신뢰할 수 있고, 확장 가능하며, 이식 가능한 메시지 브로커입니다. Spring은 RabbitMQ를 사용하여 AMQP 프로토콜을 통해 통신합니다.

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

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret

컨텍스트에 ConnectionNameStrategybean이 있으면 자동으로 구성된 ConnectionFactory에 의해 작성된 연결의 이름을 지정하는 데 자동으로 사용됩니다. 지원되는 옵션에 대한 자세한 내용은 RabbitProperties를 참조하십시오.

자세한 내용은 Understanding AMQP, the protocol used by RabbitMQ를 참조하십시오.

34.2.2 메시지 전송

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

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

	private final AmqpAdmin amqpAdmin;
	private final AmqpTemplate amqpTemplate;

	@Autowired
	public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
		this.amqpAdmin = amqpAdmin;
		this.amqpTemplate = amqpTemplate;
	}

	// ...

}

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

필요한 경우 bean으로 정의 된 org.springframework.amqp.core.Queue는 자동으로 RabbitMQ 인스턴스의 해당 대기열을 선언하는 데 사용됩니다.

작업을 다시 시도하려면 AmqpTemplate에서 재시도를 활성화 할 수 있습니다 (예 : 브로커 연결이 끊어진 경우).

spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.initial-interval=2s

재 시도는 기본적으로 비활성화되어 있습니다. RabbitRetryTemplateCustomizerBean을 선언하여 RetryTemplate을 프로그래밍 방식으로 사용자 정의 할 수도 있습니다.

34.2.3 메시지 수신

Rabbit 인프라 스트럭처가 존재하면 모든 Bean에 @RabbitListener가 어노테이션 처리되어 리스너 끝점을 만들 수 있습니다. RabbitListenerContainerFactory가 정의되어 있지 않으면 기본 SimpleRabbitListenerContainerFactory가 자동으로 구성되며 spring.rabbitmq.listener.type 속성을 사용하여 직접 컨테이너로 전환 할 수 있습니다. MessageConverter또는 MessageRecovererbean이 정의되면 자동으로 기본 팩토리와 연관됩니다.

다음 샘플 컴포넌트는 someQueue큐에 리스너 엔드 포인트를 작성합니다.

@Component
public class MyBean {

	@RabbitListener(queues = "someQueue")
	public void processMessage(String content) {
		// ...
	}

}

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

더 많은 RabbitListenerContainerFactory인스턴스를 생성해야하거나 기본 설정을 덮어 쓰려면 SpringBoot가 DirectRabbitListenerContainerFactoryConfigurerDirectRabbitListenerContainerFactoryConfigurer를 제공합니다. 자동 구성에서 사용되는 팩토리와 동일한 설정으로 aSimpleRabbitListenerContainerFactoryDirectRabbitListenerContainerFactory를 초기화하는 데 사용할 수 있습니다.

선택한 컨테이너 유형은 중요하지 않습니다. 이 두 빈은 자동 구성에 의해 노출됩니다.

예를 들어, 다음 구성 클래스는 특정 MessageConverter를 사용하는 다른 팩토리를 노출합니다.

@Configuration
static class RabbitConfiguration {

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

}

다음 예제처럼 @RabbitListener-annotated 메서드에서 팩토리를 사용할 수 있습니다.

@Component
public class MyBean {

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

}

리스너가 예외를 throw하는 상황을 처리하도록 재 시도를 활성화 할 수 있습니다.

메시지는 메시지를 받아간 worker가 정상적으로 작업을 끝마치면 RabbigMQ로 ack를 날리고, RabbitMQ는 메시지를 Queue에서 삭제하는 게 일반적인 동작!

예외가 발생하면 ack를 못받으니까 메시지를 삭제하지 못하고 계속 worker에게 전달되는 현상 발생.

------> 이 때(worker가 정상적으로 작업을 끝마치지 못했을 경우), 정해진 횟수만큼 재시도 하도록 설정 변경 가능 (RetryTemplate 사용)

기본적으로 RejectAndDontRequeueRecoverer가 사용되지만 사용자 자신의 MessageRecoverer를 정의 할 수 있습니다. 재 시도가 고갈되면 브로커가 그렇게하도록 구성된 경우 메시지가 거부되고 데드 레터 교환으로 라우팅되거나 라우팅됩니다. 기본적으로 재시도 기능은 비활성화되어 있습니다. RabbitRetryTemplateCustomizerBean을 선언하여 RetryTemplate을 프로그래밍 방식으로 사용자 정의 할 수도 있습니다.

Recoverer : 익셉션 처리!

RejectAndDontRequeueRecoverer를 상속받는 Recoverer를 구현하면 caller에 익셉션을 전달할 때 Recoverer의 recover 메소드가 호출된다. 인자로 메시지와 예외를 받을 수 있기 때문에 예외 처리를 할 수 있으며 ReQueuing이 되지 않기 때문에 Queue에 메시지를 다시 쌓지 않는다.

Important

기본적으로 재시도가 사용되지 않고 리스너에서 예외가 발생하면 배달이 무기한 재 시도됩니다. 이 동작은 다음 두 가지 방법으로 수정할 수 있습니다. defaultRequeueRejected 속성을 false로 설정하여 재 배달을 재 시도하지 않거나 AmqpRejectAndDontRequeueException을 throw하여 메시지를 거부해야 함을 알립니다. 후자는 재시도가 사용 가능하고 최대 전달 시도 횟수에 도달 할 때 사용되는 메커니즘입니다.

Last updated