본문 바로가기

Programming/Spring Boot

[Spring Boot] RabbitMQ 연동하기

반응형

안녕하세요. 남산돈가스입니다.

2020/07/31 - [Programming] - Mac에 RabbitMQ 설치 및 실행하기

 

Mac에 RabbitMQ 설치 및 실행하기

안녕하세요. 남산돈가스입니다. 오늘은 Message Broker 역할로 자주 사용되는 RabbitMQ를 Mac 환경에서 설치해보고 실행하는 포스팅을 진행하겠습니다. 제 로컬환경인 Mac OS 기준으로 설명드리며, 패키�

ibks-platform.tistory.com

지난 포스팅에서 설치한 RabbitMQ를 활용하여 Spring Boot 환경에서 간단하게 RabbitMQ의 사용법을 포스팅해보려고 합니다.

 

RabbitMQ는 오픈소스로 제공되는 메시지 브로커이며, 비동기 작업 큐의 역할을 위해 사용하고 있습니다.

Spring Boot는 이 RabbitMQ를 아주아주 간편하게 사용할 수 있도록 의존성을 제공하고 있습니다. 지금부터 이 의존성을 이용하여 RabbitMQ를 간단하게 연동해보도록 하겠습니다.

프로젝트 생성

제 로컬환경은 Mac OS이며 IDE는 IntelliJ 기준으로 설명드리겠습니다.

프로젝트명은 rabbitmqTest로 명명했으며

의존성은 Spring Web 과 Spring for RabbitMQ를 추가하였습니다.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>kr.co.ibks</groupId>
    <artifactId>rabbitmqtest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rabbitmqtest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

pom 파일입니다.

Hello World

예제는 이런 순서로 구성할 예정입니다.

  1. RabbitMQ 접속 설정
  2. Message Sender 만들기
  3. Message Listener 만들기
  4. RestController로 메시지를 보낼 수 있는 send api 만들기
  5. send api 호출하기
  6. 메시지 수신 확인하기

먼저 RabbitMQ 접속 설정을 위하여 application.yml 파일을 수정합니다.

spring:
  rabbitmq:
    host: localhost
    username: ibks
    password: *******

host는 로컬환경이므로 localhost, 계정정보는 지난 포스팅에서 생성한 계정을 사용했습니다.

다음으로 Message Sender를 구현해보겠습니다.

rabbitmq라는 패키지를 만들고 Sender.java 클래스를 생성합니다.

@Component
class Sender {
    @Autowired
    RabbitMessagingTemplate template;

    @Bean
    Queue queue() {
        return new Queue("TestQ", false);
    }

    public void send(String message) {
        template.convertAndSend("TestQ", message);
    }
}

 

메시지를 송수신하기 위한 큐를 생성한 Bean을 선언하고 "TestQ"라는 이름의 큐를 생성합니다.

생성한 큐로 입력받은 문자열 message를 전송하는 send 메서드를 생성합니다.

Sender를 통해 RabbitMQ의 TestQ라는 큐로 메시지를 발송할 수 있는 send 메서드를 만들었습니다.

다음으로는 이 send를 요청하는 API를 만들어보겠습니다.

먼저 controller라는 패키지를 생성하고 messageController.java 클래스를 생성합니다.

@RestController
public class MessageController {

    @Autowired
    Sender sender;

    @PostMapping("/messages")
    public String sendMessage(final @RequestBody Map<String,String> req ) {
        String message = req.get("message");
        try {
            sender.send(message);
            return "send message success";
        }
        catch (Exception e ){
            System.out.println(e.getMessage());
            return "send message fail";
        }
    }
}

@RestController 어노테이션을 추가하고 /messages라는 엔드포인트에 POST 메서드로 message라는 key의 데이터로 요청을 보내면 위에서 생성한 TestQ에 message key의 value값이 메시지로 전달이 됩니다. 

서비스를 실행하고 메시지가 정상적으로 RabbitMQ에 전달되었는 지 확인해보겠습니다.

Hello World!!라는 메시지를 전달한 응답으로 success를 받았습니다. 그러면 이제 RabbitMQ 콘솔에서 확인해보면,

아직 어떤 데이터를 가진 메시지인지는 확인하진 못했지만 TestQ라는 큐에 message가 1개가 생성된 것을 확인하실 수 있습니다.

그럼 다음으로 이 큐에 담긴 메시지를 Listener를 추가하여 수신받고 어떤 데이터를 가진 메시지인지 확인해보겠습니다.

다시 프로젝트로 넘어가서, rabbitmq 패키지에 Listener.java 라는 클래스를 생성합니다.

@Component
public class Listener {

    @RabbitListener(queues = "TestQ")
    public void processMessage(String content) {
        System.out.println(content);
    }
}

@RabbitListener라는 어노테이션 하나로 정말 간단하게 Listener를 구성하였습니다. 이 어노테이션에 queues 에 수신 받을 큐의 이름을 설정하면 해당 큐에 담긴 메시지를 저 메소드가 수신받아 로직을 수행하게 됩니다.

그럼 이제 서비스를 재기동하여 send api를 이용해 메시지를 큐에 넣고 그 메시지를 Listener가 수신하는 지 확인해보겠습니다.

총 다섯 번의 API를 요청했는데 그 메시지를 즉시 수신하여 print하고 있는 것을 확인했습니다.

이렇게 RabbitMQ를 이용하여 정말 간단한 메시지 발행 / 구독 프로세스를 경험해보았습니다.

위 예제에선 테스트를 위해 Sender와 Listener를 같은 서비스 안에 구성하였지만 실제 워크로드에서는 분명 메시지 발행 주체와 수신 주체는 분리하여 아키텍처를 구성하시는 것에 유의하셔야합니다.

감사합니다.