•
이 장에서 배우는 내용
◦
비동기 메시지 전송
◦
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를 빈 메소드에 지정하면 푸시 모델의 형태로 컨슈머에게 메시지가 전송될 수 있다.