ActiveMQ와 JMS를 사용한 SpringBoot 메시지
- 이벤트 기반 통신은, 여러 서비스 및 관련 도메인 모델에 변경 사항이나 메시지들을 전파할 때 중요하다.
- 변경사항이 발생했을 경우, 여러 서비스/모델 에서 변경 사항을 적용 할 방법이 필요
- 메시지큐를 사용하면 안정적인 통신과 기능적용이 가능하다
- 메시지큐에는 여러가지가 있지만, 이번에는 ActiveMQ를 사용한다
Event 기반 통신 / 아키텍처
이벤트기반 통신은 여러 마이크로 서비스 및 관련 도메인 모델에 변경사항을 전파 할 때 중요하다
변경 사항이 발생했을 경우, 여러 서비스/모델 에서 변경 사항을 적용 할 방법이 필요하다
이벤트 기반 아키텍처를 달성하기 위한 방법은 여러가지가 있지만, 많은 경우에 메시징 패턴을 사용한다
RabbitMQ, ActiveMQ, Apache Kafka 등과 같은 도구들은 메시징 패턴에 사용되는 메시지 브로커이다
이 중, ActiveMQ를 사용해 메시지를 보내고 받아보려고 한다
ActiveMQ 세팅하기
ActiveMQ는 메시지 브로커로써 메시지를 보내고 받을 수 있는 기능을 제공한다
ActiveMQ는 공식페이지에서 다운받아도 괜찮고, docker-compose 를 통해서 설치해도 된다
공식페이지에서 다운받으려면, 아래 페이지에서 사용하면 된다
- ActiveMQ 공식페이지 링크: http://activemq.apache.org/activemq-5151-release.html
나는 개발환경에 따로 설치하는 것 보다, docker를 선호해서 docker-compose를 사용하려고 한다
version: '3'
services:
activemq:
image: rmohr/activemq
container_name: activemq
ports:
- "8161:8161"
- "1883:1883"
- "5672:5672"
- "61613:61613"
- "61616:61616"
- "61614:61614"
- ActiveMQ Web Console은 8161, ActiveMQ Broker는 61616 포트를 사용한다
- 기타 다른 1883, 5672, 61613, 61614 포트는 다른 프로토콜을 사용한다
- docker 로그를 확인하면 ActiveMQ의 포트를 모두 확인할 수 있다
SpringBoot 프로젝트 만들기
- springboot 버전은 2.7.9-SNAPSHOT 버전을 사용한다
plugins { id 'java' id 'org.springframework.boot' version '2.7.9-SNAPSHOT' id 'io.spring.dependency-management' version '1.0.15.RELEASE' }
SpringBoot Gradle 적용
- spring web과 activemq 를 넣는다
dependencies { implementation 'org.springframework.boot:spring-boot-starter-activemq' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
SpringBoot Resource 설정
- resources/application.properties 파일 내부에 ActiveMQ의 설정을 넣는다
spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin
SpringBoot Application 작성하기
Config
- Config 패키지를 만들고, 아래의 JmsCOnfig 클래스를 만든다
package com.example.springbootactivemq.config; import org.apache.activemq.command.ActiveMQQueue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.jms.Queue; @Configuration public class JmsConfig { @Bean public Queue queue() { return new ActiveMQQueue("test-queue"); } }
consumer
- consumer 패키지를 만들고, 아래와같이 컨슈머를 만든다
package com.example.springbootactivemq.consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.annotation.JmsListener; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Component; @Component public class MessageConsumer { private final Logger logger = LoggerFactory.getLogger(MessageConsumer.class); @JmsListener(destination = "test-queue") public void receiveMessage(String message) { logger.info("Received message: {}", message); } @JmsListener(destination = "test-queue") @SendTo("greet-queue") public String receiveMessageAndReply(String message) { logger.info("Received message: {}", message); return "Hello " + message; } @JmsListener(destination = "greet-queue") public void receiveGreeting(String message) { logger.info("Received greeting: {}", message); } }
@JmsListener
를 통해서 메시지를 받는다.test-queue
라는 큐에 메시지가 들어오면,receiveMessage
메소드가 실행된다@SendTo
를 통해서 메시지를 보낼 수 있다.test-queue
라는 큐에 메시지가 들어오면,receiveMessageAndReply
메소드가 실행된다@SendTo
에 지정한greet-queue
큐에 메시지를 보낸다
receiveGreeting
메소드는greet-queue
라는 큐에 메시지가 들어오면 실행된다
controller
- controller를 만들어 API를 통해 Message를 보내는 역할을 만든다
package com.example.springbootactivemq.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.jms.core.JmsTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.jms.Queue; @RestController @RequestMapping("/api") public class MessageController { @Autowired private Queue queue; @Autowired private JmsTemplate jmsTemplate; @GetMapping("message/{message}") public ResponseEntity<String> publishMessage(@PathVariable("message") final String message) { jmsTemplate.convertAndSend(queue, message); return new ResponseEntity(message, HttpStatus.OK); } }
실행
/api/message/hello
를 호출하면,test-queue
에 메시지가 들어가고,greet-queue
에 메시지가 들어간다- 이 모든 과정을
ActiveMQ Web Console
에서 볼 수 있다
댓글남기기