[Spring] ActiveMQ - ActiveMQ 정의, ActiveMQ의 주요 개념(MOM, AQMP, MQTT), Spring에서 ActiveMQ 사용하기

김희정·2024년 1월 9일
0

Spring

목록 보기
14/16

💎 들어가며

1. Key Terms in ActiveMQ

ActiveMQ 슬로건

ActiveMQ는 자바 기반의 오픈소스 메세지 브로커(Message Broker)입니다. ActiveMQ는 교차 언어 클라이언트 및 프로토콜을 제공합니다.

  • Java, C, C++, C# ⇒ OpenWire
  • C, Ruby, Perl, Python, PHP, 등 ⇒ Stomp 지원
  • AMQP v1.0 지원 ⇒ Artemis
  • MQTT v3.1 지원 ⇒ IoT 환경 지원

1.1 Message Broker

메시지 브로커는 애플리케이션, 시스템 및 서비스가 서로 간에 통신하고 정보를 교환할 수 있도록 해주는 중간자 소프트웨어입니다.

Message Broker
출저 - What is Message Broker


송신자(Producer)와 수신자(Consumer)는 직접 연결하지 않고도 브로커(Message Broker)를 통해 서로 메세지를 주고 받을 수 있습니다.


1.2 MOM, MQ, AMQP

MOM은 독립된 서비스간 데이터를 주고받을 수 있는 형태의 미들웨어 아키텍쳐 개념, MQ는 MOM을 구현한 시스템, AMQP는 MOM을 구현한 프로토콜, JMS는 MOM을 구현한 자바 API를 의미합니다.


📬 MOM (Message Oriented Middleware)

MOM (Message Oriented Middleware, 메시지 지향 미들웨어, 이하 MOM)이란 독립된 서비스 간 데이터를 주고받을 수 있는 형태의 미들웨어를 의미합니다.

함수 호출이나 공유 메모리를 이용하여 애플리케이션 간 통신하는 것이 아니라, 메시지 교환을 이용하는 중간 계층에 대한 인프라 아키텍처 개념입니다.

MOM을 통해 여러 분산 시스템 간의 중간자 역할로 결합성을 낮추고, 이들이 서로 실시간 비동기식 데이터를 교환할 수 있도록 도와줍니다.


📬 MQ (Message Queue)

Queue란 선입선출(First in First out) 구조를 가진 자료구조입니다. 메세지 큐(Message Queue)Queue라는 자료구조를 채택해서 메세지를 전달하는 시스템이며, 메세지 지향 미들웨어(MOM)을 구현한 시스템입니다.

메세지 큐를 통해 메세지를 전달하려면 메세지를 전송자와 수신자가 필요하겠죠? 여기서 메세지를 발행하고 전달하는 송신자를 Producer 라고 하며, 메세지를 받아서 소비하는 수신자를 Consumer 라고 합니다.

메세지 큐는 Producer 와 Consumer 의 메세지 전달 역할을 하는 매개체입니다.

MQ의 송신자와 수신자는 다양한 표현으로 설명될 수 있습니다.

송신자 (보내는 쪽)수신자 (받는 쪽)
SenderReceiver
ProducerConsumer
PublisherSubscriber

MQ의 특징

특징설명
비동기(Asynchronous)Queue에 넣어두기 때문에 나중에 처리할 수 있다.
분리 또는 비동조(Decoupling)애플리케이션과 분리할 수 있다.
탄력성(Resilience)일부가 실패 시 전체에 영향을 받지 않는다.
과잉(Redundancy)실패 할 경우 재실행이 가능하다.
보증(Guarantees)작업이 처리된 걸 확인할 수 있다.
확장성(Scalable)다수의 프로세스들이 큐에 메시지를 보낼 수 있다.

AMQP (Advanced Message Queuing Protocol)

MOM을 위한 표준 응용 계층 프로토콜입니다. AMQP의 정의 기능들은 메시지 지향, 큐잉, 라우팅, 신뢰성 보안입니다.

과거의 미들웨어 표준들은 API 레벨(ex. JMS)에서 등장하였으나 여러 구현체 간 상호 운용성을 제공하지 않아 구현체간 지원이 불가했습니다.

그래서, 서로 다른 시스템들 간의 최대한 효율적인 방법으로 메세지를 교환하기 위해 AMQP 프로토콜이 등장하게 되었습니다.


JMS (Java Message Service)

JMS는 자바 기반의 MOM API이며, 둘 이상의 클라이언트 간에 메세지를 서로 주고 받을 수 있는 기능을 지원합니다.


1.3 MQTT

MQTT(Message Queueing Telemetry Trasport)는 ISO 표준 (ISO/IEC PRF 20922) 발행-구독 모델 기반의 메시징 프로토콜입니다.

MQTT는 IoT 혹은 대규모 트래픽과 같은 네트워크 대역폭이 제한되는 원격 통신을 위해 만들어진 프로토콜로 TCP/IP 프로토콜 위에서 동작합니다.

MQTT의 통신 방식

MQTT 통신 전개도

  • 연결지향적: MQTT 브로커와 연결을 요청하는 클라이언트는 TCP/IP 소켓 연결을 한 후, 명시적으로 연결을 끊거나 네트워크 사정에 의해 연결이 끊어질 때까지 상태를 유지합니다.

  • 브로커를 통한 통신: MQTT의 발행-구독 메시징 패턴은 오로지 브로커를 통해서만 통신할 수 있습니다. 개설된 Topic에 메시지를 발행하면 해당 Topic을 구독하는 클라이언트들에게 메시지를 발행할 수 있습니다. (1:1, 1:N 통신 가능)


2. ActiveMQ

2.1 Java Version

ActiveMQ는 Java 기반의 브로커이기 때문에 ActiveMQ 설치에 앞서 Java를 설치해주어야합니다.

ActiveMQ 버전 별로 자바 버전도 상이하니 유의해서 설치해야 합니다.

  • ActiveMQ 5.15.x support Java 8+
  • ActiveMQ 5.17.x support Java 11+
  • ActiveMQ 6.x support Java 17+

2.2 ActiveMQ Install

ActiveMQ는 메세지 브로커로 메시지 서버로 이해하시면 됩니다. 즉, 서버를 설치하고 실행해야 한다는 것이지요.

ActiveMQ 공식홈페이지에서 다운로드 받을 수 있습니다.

ActiveMQ 다운로드 홈페이지

ActiveMQ 설치

ActiveMQ 설치 디렉터리

받은 압축파일을 해제하여 설치 디렉터리로 만듭니다.

  • ActiveMQ 실행: bin > activemq.bat
  • ActiveMQ 서비스 등록: bin > win64 | win32 > InstallService.bat

ActiveMQ 기본 Port

ActiveMQ는 기본적으로 두가지 포트(61616, 8161)를 갖고 있습니다. 61616은 broker로 사용되고, 8161은 웹 관리 콘솔로 사용됩니다.

ActiveMQ가 정상적으로 실행되었다면, http://localhost:8161 로 웹 관리 콘솔에 접속할 수 있습니다.

ActiveMQ 관리 콘솔

해당 콘솔을 통해 ActiveMQ 의 Producer, Consumer, Queue, Topic 등 다양한 정보를 편리하게 확인할 수 있습니다.

2.3 Message Delivery

ActiveMQ는 큐(Queue)토픽(Topic)이라는 메시지 전달 방식을 지원합니다.

Message Delivery

  • Queue: 1:1, 메시지를 수신 대기 중인 클라이언트 중 하나에게 전달하는 방식
  • Topic: 1:N, 메시지를 여러 구독자에게 전달하는 방식

3. Spring Boot + ActiveMQ

3.1 구현하기 전에

Spring에서 ActiveMQ 클라이언트를 구현하기 앞서 필요한 개념을 먼저 살펴보겠습니다.

ActiveMQ는 JMS를 기반으로 통신을 제어하는 메시지 큐입니다.

JMS의 주요 개념

  • Message Broker : 메세지를 목적지로 건네주는 중개자
  • Destination : 메세지를 수신받을 주소지 (Consumer 의 주소)
  • Queue : 큐의 메세지를 Consumer 간 경쟁하여 가져가는 모델
  • Topic : Topic 에 메세지를 발행 및 구독하여 메세지를 교환하는 모델, Topic 구독자는 모두 동일하게 메세지를 가져감

JMS 연결 순서

  1. 메시지 중개기에 JMS 연결 팩토리(connection factory)를 생성
  2. 큐, 토픽 중 하나로 JMS 목적지를 생성
  3. 연결 팩토리에서 JMS 서버에 연결
  4. JMS 연결로부터 JMS 세션을 획득
  5. 메시지 생산기/소비기로 JMS 메시지를 송수신
  6. JMSException은 Exception 처리
  7. JMS 세션 및 연결을 닫기
    public boolean send(RequestMessage messages) {
        try (ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
             ActiveMQSession session = (ActiveMQSession) connection.createSession(false, ActiveMQSession.AUTO_ACKNOWLEDGE)) {
            connection.start();

            MessageProducer producer = session.createProducer(queue);
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            Message m = MessageConverter.convertObjectToMessage(message, session);
            producer.send(m);

            log.info("Status: INFO, Message: ActiveMQ 메세지 전송. 메세지: {}", message);
        
        } catch (JMSException e) {
            log.error("Status: ERROR, MSG: JMS 작업 중 에러가 발생하였습니다. - {}", e.getMessage());
            return false;
        } catch (JsonProcessingException e) {
            log.error("Status: ERROR, MSG: Json Parsing 중 에러가 발생하였습니다. - {}", e.getMessage());
            return false;
        }

        return true;
    }

JmsTemplate

JMS API는 자바에서 제공하는 기본 API로 JDBC와 유사하게 연결부터 데이터 송수신까지 수많은 보일러플레이트 코드를 작성해야합니다.

스프링은 템플릿 기반으로 JMS 코드를 단순화하는 솔루션을 제공합니다. JMS 템플릿 클래스 JmsTemplate을 이용하면 소량의 코드만으로도 JMS 메시지를 주고받을 수 있습니다.

3.2 Bean Configuration

application.yml

application.yml 파일에 사용할 설정 값을 입력합니다.

spring:
  activemq:
    broker-url: tcp://localhost:61616 # ActiveMQ Broker URL
    user: admin       # ActiveMQ 웹 관리 콘솔 아이디
    password: admin   # ActiveMQ 웹 관리 콘솔 비밀번호
    
activemq:
  queue:
    name: sample-queue # 사용할 Queue 이름

Configuration

// ActiveMQ Class 내부
@ConfigurationProperties(
    prefix = "spring.activemq"
)
public class ActiveMQProperties {
    private static final String DEFAULT_NETWORK_BROKER_URL
    				= "tcp://localhost:61616";
    private String brokerUrl;
    private String user;
    private String password;
    private Duration closeTimeout = Duration.ofSeconds(15L);
    private boolean nonBlockingRedelivery = false;
    private Duration sendTimeout = Duration.ofMillis(0L);
    @NestedConfigurationProperty
    private final JmsPoolConnectionFactoryProperties pool = 
    				new JmsPoolConnectionFactoryProperties();
    private final Packages packages = new Packages();
}

💎 References

💎 마치며

profile
Java, Spring 기반 풀스택 개발자의 개발 블로그입니다.

0개의 댓글