////
Search
Duplicate
🔑

Chapter 8. 비동기 메시지 전송하기

이 장에서 배우는 내용
비동기 메시지 전송
JMS, RabbitMQ, Kafka를 사용해서 메시지 전송하기
브로커에서 메시지 가져오기
메시지 리스닝하기
이전에는 RestTemplate과 Traverson을 사용한 동기화 통신을 알아보았다. 그러나 이것만이 개발자가 사용할 수 있는 어플리케이션 간의 통신 형태는 아니다.
비동기 메시징은 어플리케이션 간에 응답을 기다리지 않고 간접적으로 메시지를 전송하는 방법이다. 따라서 통신하는 어플리케이션 간의 결합도를 낮추고 확장성을 높여준다.
⇒ 사용자의 행위에 따라 미션이 달성되고 보상이 지급되는 방식이라면 사용자의 행위와 미션 달성 확인 로직을 분리할 수 있을 것 같다.

1. JMS로 메시지 전송하기

JMS(Java Message Service)는 두 개 이상의 클라이언트 간에 메시지 통신을 위한 공통 API를 정의하는 자바 표준이다.
스프링은 JmsTemplate이라는 템플릿 기반의 클래스를 통해 JMS를 지원한다. JmsTemplate을 사용하면 프로듀서가 큐와 토픽에 메시지를 전송하고 컨슈머는 그 메시지들을 받을 수 있다.
스프링은 메시지 기반의 POJO도 지원한다. POJO는 큐나 토픽에 도착하는 메시지에 반응하여 비동기 방식으로 메시지를 수신하는 간단한 자바 객체다.

1. JMS 설정하기

JMS를 사용하려면 JMS 클라이언트를 프로젝트의 빌드에 추가해야 한다. 이후 Artemis와 ActiveMQ 기존버전 중 어떤 브로커를 사용할지 결정해야 한다.
어떤 브로커를 선택하든 메시지를 송수신하는 코드 작성방법에는 영향을 주지 않으며 브로커에 대한 연결을 생성하기 위한 스프링 구성 방법만 다르다.
연결을 구성하기 위해 스프링의 구성 요건에 브로커의 호스트, 포트, 사용자(Optional), 사용자 암호(Optional)을 제공해주어야 한다.
각 브로커마다 특징적인 구성 요소를 가질 수 있으므로 이를 잘 확인하고 연결해주어야 한다.

2. JmsTemplate을 사용해서 메시지 전송하기

JMS 스타터 의존성이 빌드에 지정되면 메시지를 송수신하기 위해 주입 및 사용할 수 있는 JmsTemplate을 스프링 부트가 AutoConfiguration한다.
JmsTemplate은 다음을 비롯하여 메시지 전송에 유용한 여러 메소드를 갖고 있다.
// 원시 메시지를 전송한다. void send(MessageCreator messageCreator) throws JmsException; void send(Destination destination, MessageCreator messageCreator) throws JmsException; void send(String destinationName, MessageCreator messageCreator) throws JmsException; // 객체로부터 변환된 메시지를 전송한다. void convertAndSend(Object message) throws JmsException; void convertAndSend(Destination destination, Object message) throws JmsException; void convertAndSend(String destinationName, Object message) throws JmsException; // 객체로부터 변환되고 전송에 앞서 후처리되는 메시지를 전송한다. void convertAndSend(Object message, MessagePostProcessor postProcessor) throws JmsException; void convertAndSend(Destination destination, Object message, MessagePostProcessor postProcessor) throws JmsException; void convertAndSend(String destinationName, Object message, MessagePostProcessor postProcessor) throws JmsException;
Java
복사
이처럼 실제로는 send()convertAndSend()의 두 개 메소드만 있으며 각 메소드는 서로 다른 매개변수를 지원하기 위해 오버로딩되어있다.
send() 메소드는 Message 객체를 생성하기 위해 MessageCreator 객체를 필요로 한다.
변환된 메시지를 전송만 하는 convertAndSend() 메소드 3개는 Object 타입 객체를 인자로 받아 내부적으로 Message 타입으로 변환한다.
객체로 변환되고 후처리되는 메시지를 전송하는 convertAndSend() 메소드 3개는 Object 타입 객체를 Message 타입으로 변환하고 메시지 전송 전 Message의 커스터마이징을 수행하도록 MessagePostProcessor도 인자로 받는다.

3. JMS 메시지 수신하기

메시지를 수신하는 방식에는 폴 모델푸시 모델이 있다.
폴 모델은 메시지를 요청하고 도착할 때까지 기다리며 푸시 모델은 메시지가 수신 가능하게 되면 자동으로 전달한다.
JmsTemplate의 수신 관련 메소드는 다음과 같다.
Message receive() throws JmsException; Message receive(Destination destination) throws JmsException; Message receive(String destination) throws JmsException; Object receiveAndConvert() throws JmsException; Object receiveAndConvert(Destination destination) throws JmsException; Object receiveAndConvert(String destination) throws JmsException;
Java
복사
receive() 메소드는 원시 메시지를 수신하는 반면 receiveAndConvert() 메소드는 메시지를 도메인 타입으로 변환하기 위해 구성된 메시지 변환기를 사용한다.

요약

어플리케이션 간 비동기 메시지 큐를 이용한 통신 방식은 간접 계층을 제공하므로 어플리케이션 간의 결합도는 낮추면서 확장성은 높인다.
스프링은 JMS, RabbitMQ 또는 아파치 카프카를 사용해서 비동기 메시징을 지원한다.
스프링 어플리케이션은 템플릿 기반의 클라이언트인 JmsTemplate, RabbitTemplate 또는 KafkaTemplate을 사용해서 메시지 브로커를 통한 메시지 전송을 할 수 있다.
메시지 수신 어플리케이션은 같은 템플릿 기반의 클라이언트들을 사용해서 풀 모델 형태의 메시지 소비자를 만들 수 있다.
메시지 리스너 어노테이션인 @JmsListener, @RabbitListener 또는 @KafkaListener를 빈 메소드에 지정하면 푸시 모델의 형태로 컨슈머에게 메시지가 전송될 수 있다.