본문 바로가기

java/스프링인액션

8. 비동기 메시지 전송

비동기 메시지

어플리케이션 간에

응답을 기다리지 않고

간접적으로 메시지를 전송하는 방법

 

ex)

타코 클라우드 웹 사이트 ------------------> 주방 

                                 주문 데이터 전송

 

 

8.1 JMS 메시지 전송

Java Message Service

 

JmsTemplate 템플릿 기반의 클래스를 통해 JMS를 지원한다.

프로듀서 큐와 토픽에 메시지를 전송함  
   
토픽    
컨슈머 메시지를 받는다  
POJO plain Old Java Object 큐, 토픽에 도착하는 메시지에 반응하여 비동기 방식으로 메시지를 받는
자바 객체
 
브로커 메시지를 전달해줌
아파치 ActiveMQ
아파치 ActiveMQ Artemis

61616 포스 리스닝
 

 

1. JMS 설정

브로커 스타터 의존성을 빌드에 추가한다.

 

<-- 브로커 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

<-- 브로커 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-artemis</artifactId>
</dependency>

 

인증 정보

spring.artemis.host  artemis.tacocloud.com 브로커의 호스트
spring.artemis.port 61617 브로커의 포트
spring.artemis.user tacoweb 브로커를 사용하기 위한 사용자
spring.artemis.password 13tm31n 브로커를 사용하기 위한 사용자 암호

 

 

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

JMS 스타터 의존성을 추가 --> JmsTemplate를 스프링 부트가 자동-구성 한다

없다면?

   1) 베시지 브로커 연결

   2) 세션 생성 코드

   3) 예외 코드

 

 

JmsTemplate 메서드

send(...)

convertAndSend(...)

 

 

MessageCreator Message 객체를 생성하기 위해
MessagePostProcessor 메시지가 전송되기 전, Message의 커스터마이징
Destination JMS 메시지의 도착지
메시지를 사용하는 곳
큐, 토픽

 

 

// send함수는 MesseageCreator mc를 매개변수로 한다.
void send(MesseageCreator mc) throws JmsException;


@service
public class JmsOrderMessagingService implements OrderMessagingService{
 private JmsTemplate jms;
 
 @Autowired
 public JmsOrderMessagingService(JmsTemplate jms){
 	this.jms = jms;
 }//생성자 함수
 
 // 1. MesseageCreator 만드는 방법 
 //-> new MessageCreator() 객체 생성 -> createMessage(session)오버라이드
 // order 내용 + session을 넣은 => MesseageCreator mc 객체가 전달되는 것과 같음
 @Override
 public void sendOrder(Order order){
 	jms.send(new MessageCreator(){
 		@Override
        public Message createMessage(Session session) throws JMSException{
        	return session.createObjectMessage(order);
        }//createMessage end
     });//jms.send end
  }
  
  
  // 2. MesseageCreator 만드는 방법 : 람다 사용
  // createMessage 생략 가능
  // order 내용 + session을 넣은 => MesseageCreator mc 객체가 전달되는 것과 같음
  @Override
  public void sendOrder(Order order){
  	jms.send(session -> session.createObjectMessage(order)); 
   }

 

 

기본 도착지 설정

spring:
   jms: 
     template:
          dafault-destination : tacocloud.order.queue

 

다른 도착지 설정

1) Destination 빈 선언 --> 메시지 전송 수행하는 빈에 주입

// Destination 빈 선언
@Bean
public Destination orderQueue(){// 아르테미스의 class다.
	return new ActiveMQQueue("tacocloud.order.queue"); //목적지 : 주문.큐
}

---------------------------------------------------------------------------------------
//JmsOrderMessagingService에 주입되면 
// send()를 호출할 때 이 빈을 사용하여 메시지 도착지를 지정할 수 있다

private Destination orderQueue;

@Autowired
public JmsOrderMessagingService(JmsTemplate jms, Destination orderQueue){
 this.jms = jms;
 this.orderQueue = orderQueue;
 }
 .........
 
 @Override
 public void sendOrder(Order order){
 	jms.send(
    	orderQueue,
        session-> session.createObjectMessage(order));
  }
  
  // 도착지 이름 지정하는게 더 쉬움
   @Override
 public void sendOrder(Order order){
 	jms.send(
    	"tacocloud.order.queue",
        session-> session.createObjectMessage(order));
  }

Destination 객체를 사용해서 

메시지 도착지를 지정하면 도착지 이름만 지정하는 것보다 다양하게 도착지를 설정할 수 있다.

 

 

 

메시지 변환하고 전송하기

   @Override
 public void sendOrder(Order order){
 	jms.convertAndSend("tacocloud.order.queue", order);
  }

order객체는 Message 객체로 변환된 후 전송된다.

 

메시지 변환기 구현

Mapping잭슨2메시지변환기
(Serializable인터페이스 제약 피하기)
잭슨 2 JSON  라이브러리를 사용해
메시지를 JSON으로 변환
Marshalling메시지변환기 JAXB를  사용해
메시지를 XML로 변환
Messaging메시지변환기 받은 메시지의 메시지 변환기를 사용해
해당 메시지를 Message객체로 변환
JMS 헤더와 연관된 헤더매퍼를 
표준 메시지 헤더로 변환
SimpleMessageConverter
(기본)
문자열을 텍스트메시지로
바이트 배열을 바이트메시지로
맵을 맵메세지로
Serializable 객체를 Object Message로
변환
@Bean
public MappingJackson2MessageConverter messageConverter(){
	MappingJackson2MessageConverter mc = new MappingJackson2MessageConverter();
    mc.setTypeIdPropertyName("_typeId");
    return mc;//변환기 인스턴스 반환
  }
  
  ----------------------------------------------------------------------------------
//유연하게 바꾸기
@Bean
public MappingJackson2MessageConverter messageConverter(){
	MappingJackson2MessageConverter mc = new MappingJackson2MessageConverter();
    mc.setTypeIdPropertyName("_typeId");//_typId 속성에 전송되는 패키지 전체 경로의 클래스 이름
    
    Map<String, Class<?>> tims = new HashMap<String, Class<?>>();
    tim.put("order", Order.class);//Order클래스를 order라는 타입ID로 매핑
    mc.setTypeIdMappings(tims);//메시지 변환기 빈을 변경
    // order 값이 전달된다.
    // 주문 데이터가 다른 패키지에 다른 클래스 이름으로 구현 가능

    return mc;//변환기 인스턴스 반환
  }

 

'java > 스프링인액션' 카테고리의 다른 글

Spring in Action  (0) 2021.12.12
10. 리액터  (0) 2021.12.12
[8.3] 카프카 사용하기  (0) 2021.12.04
[6.3] 스프링 데이터 REST  (0) 2021.11.27
[6.3]  (0) 2021.11.27