2 분 소요


  • Event-driven communication is important when propagating changes or messages to multiple services and related domain models.
  • When changes occur, a method is needed to apply changes across multiple services/models
  • Using message queues enables reliable communication and feature implementation
  • There are various message queues, but this time we’ll use ActiveMQ

Event-Based Communication / Architecture

Event-based communication is important when propagating changes to multiple microservices and related domain models.

When changes occur, a method is needed to apply changes across multiple services/models.

There are various ways to achieve event-driven architecture, but messaging patterns are used in many cases.

Tools like RabbitMQ, ActiveMQ, Apache Kafka, etc. are message brokers used in messaging patterns.

Among these, we’ll try sending and receiving messages using ActiveMQ.

Setting Up ActiveMQ

ActiveMQ is a message broker that provides functionality to send and receive messages.

ActiveMQ can be downloaded from the official page or installed through docker-compose.

To download from the official page, use the link below:

  • ActiveMQ official page link: http://activemq.apache.org/activemq-5151-release.html

I prefer docker over installing separately in the development environment, so I’ll use 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 uses port 8161, ActiveMQ Broker uses port 61616
  • Other ports 1883, 5672, 61613, 61614 use different protocols
  • You can check all ActiveMQ ports by viewing docker logs

Creating SpringBoot Project

  • Using springboot version 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'
      }
    

Applying SpringBoot Gradle

  • Add spring web and 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 Configuration

  • Add ActiveMQ configuration inside resources/application.properties file
      spring.activemq.broker-url=tcp://localhost:61616
      spring.activemq.user=admin
      spring.activemq.password=admin
    

Writing SpringBoot Application

Config

  • Create a Config package and create the JmsConfig class below
      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

  • Create a consumer package and create the consumer as follows
      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);
          }
      }
    
    • Messages are received through @JmsListener. When a message enters the test-queue queue, the receiveMessage method is executed
    • Messages can be sent through @SendTo. When a message enters the test-queue queue, the receiveMessageAndReply method is executed
      • Sends a message to the greet-queue queue specified in @SendTo
    • The receiveGreeting method executes when a message enters the greet-queue queue

Controller

  • Create a controller to send Messages through API
      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);
          }
      }
    

Execution

  • When calling /api/message/hello, a message goes into test-queue, and a message goes into greet-queue
  • All of this process can be viewed in the ActiveMQ Web Console

댓글남기기