AMQP(Advanced Message Queuing Protocol)란 ?
메시지 지향 미들웨어(MOM) 시스템 간에 통신하기 위한 개방형 네트워크 프로토콜이다.
간단히 말해서, 송신자(Producer)와 수신자(Consumer) 사이에서 메시지를 안전하게 교환하는 표준 프로토콜이다.
AMQP는 Queue, Exchange, Binding이라는 개념으로 구성된다.
개발을 하다보면 여러 서버를 구성하고, 서로 상호 작용하는 방식으로 구성하게 된다. 이런 상황에서 서버들은 서로 정보를 주고받아야 하는 상황이 발생한다.
그러나 HTTP 통신은 요청을 보내면 응답을 받을 때까지 요청을 보낸 서버의 수행이 중단된다. 이렇게 되면 여러 서버에 동시에 정보를 전달하기 어려워진다. 이런 상황에서 AMQP를 이용하게 되면 Message Broker 라는 미들웨어를 활용해서 비동기식으로 메시지를 전달할 수 있게 된다.
AMQP를 구현한 오픈소스 메시지 브로커이다.
나는 여기서 RabbitMQ를 써보기로 한다. RabbitMQ는 다운받아서 로컬에서도 작동시킬 수 있지만 CloudAMQP라는 사이트에서 회원가입만 진행하고, 웹상에서 활용할 수도 있다. 나는 후자의 방법을 이용했고 SpringBoot를 사용했다. 먼저 새로운 인스턴스를 생성해 준다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'com.google.code.gson:gson:2.9.0'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
}
spring:
rabbitmq:
username: <RabbitMQ 계정>
password: <RabbitMQ 비밀번호>
host: <RabbitMQ 서버>
virtual-host: <virtual host>
로컬의 경우에는 RabbitMQ의 초기 설정은 ID(user): admin, Password: <호스트 이름>이다. CloudAMQP는 name을 클릭하면 알 수 있다. host에는 dingo.rmq.cloudamqp.com 를 넣어주었다.
그럼 아래와 같은 데이터를 볼 수 있다.
Producer와 Consumer를 생성해야 한다. Producer에는 작업의 Entity를 생성하고, Repository를 만든다. Repository는 JpaRepository를 상속받아 만들었다.
작업 생성 DTO, 처리하는 서버에 데이터를 전달하는 DTO, 조회를 위해서 정보를 반환하는 DTO, 작업의 상태를 확인하는 DTO를 만들었다.
Queue를 정의하는 Config를 만든다.
@Configuration
public class PdConfig {
@Bean
public Queue queue(){
return new Queue("test-queue", true, false, true);
}
}
여기서 Queue는 name, durable, exclusive, autoDelete의 값을 설정할 수 있다.
name은 Queue를 구분 짓고, 작업 처리 시 이름을 활용하여 Queue를 찾는 데 이용된다.
durable은 서버 종료 이후에도 Queue를 유지할지를 설정한다.
exclusive는 해당 서버에만 사용하는지 설정한다.
autoDelete는 사용되지 않는 상황에서도 Queue 유지하는지의 설정이다.
rabbitTemplate.convertAndSend(
Queue.getName(), gson.toJson(payload));
해당 요청을 Post하게 되면 Queue에 작업이 쌓이는 것을 확인할 수 있다.
다음으로 Consumer를 설정하여, Queue에 있는 작업을 처리해 본다.
나머지는 모두 동일하며, 해당 작업을 처리하기 위해서는 Consumer의 Config에서 Producer의 Config의 name과 동일하게 만들어야 한다.
Consumer의 Service에 작업을 처리해 주는 메소드를 만든다.
여기서 RabbitHandler라는 어노테이션을 이용하게 되는데, 이 어노테이션은 이 클래스가 Consumer의 Config에서 정의한 Queue에 적재되는 메세지를 처리하는 클래스임을 나타낸다.
결과는 위와 같고, Queue에서 해당 작업을 꺼내 처리하게 된다.
RabbitMQ를 통해 간단한 작업을 해 보았는데, 나름 신선했고 RabbitMQ를 활용하여 비동기적으로 처리하면서 어떻게 코드의 유연성과 확장성을 향상시킬 수 있는지에 대한 통찰을 했다.
큐를 통해 데이터의 흐름을 조절하고, 시스템 간 통신을 효율적으로 관리하는 방법에 대한 이해가 조금 생긴 것 같다만, 이정도로 사용할 줄 안다고는 할 수는 없을 것 같다. 한번은 팀원이 RabbitMQ를 사용하여 결제 시스템을 고도화시킨 적이 있었다. 다음에는 결제서비스를 이해해보기로 한다.