ActiveMQ
는 자바 기반의 오픈소스 메세지 브로커(Message Broker)
입니다. ActiveMQ는 교차 언어 클라이언트 및 프로토콜을 제공합니다.
OpenWire
Stomp
지원AMQP
v1.0 지원 ⇒ ArtemisMQTT
v3.1 지원 ⇒ IoT 환경 지원메시지 브로커는 애플리케이션, 시스템 및 서비스가 서로 간에 통신하고 정보를 교환할 수 있도록 해주는 중간자 소프트웨어입니다.
송신자(Producer)와 수신자(Consumer)는 직접 연결하지 않고도 브로커(Message Broker)를 통해 서로 메세지를 주고 받을 수 있습니다.
MOM
은 독립된 서비스간 데이터를 주고받을 수 있는 형태의 미들웨어 아키텍쳐 개념, MQ
는 MOM을 구현한 시스템, AMQP
는 MOM을 구현한 프로토콜, JMS
는 MOM을 구현한 자바 API를 의미합니다.
MOM (Message Oriented Middleware, 메시지 지향 미들웨어, 이하 MOM)이란 독립된 서비스 간 데이터를 주고받을 수 있는 형태의 미들웨어를 의미합니다.
함수 호출이나 공유 메모리를 이용하여 애플리케이션 간 통신하는 것이 아니라, 메시지 교환을 이용하는 중간 계층에 대한 인프라 아키텍처 개념입니다.
MOM을 통해 여러 분산 시스템 간의 중간자 역할로 결합성을 낮추고, 이들이 서로 실시간 비동기식 데이터를 교환할 수 있도록 도와줍니다.
Queue
란 선입선출(First in First out) 구조를 가진 자료구조입니다. 메세지 큐(Message Queue)
란 Queue
라는 자료구조를 채택해서 메세지를 전달하는 시스템이며, 메세지 지향 미들웨어(MOM)
을 구현한 시스템입니다.
메세지 큐를 통해 메세지를 전달하려면 메세지를 전송자와 수신자가 필요하겠죠? 여기서 메세지를 발행하고 전달하는 송신자를 Producer 라고 하며, 메세지를 받아서 소비하는 수신자를 Consumer 라고 합니다.
메세지 큐는 Producer 와 Consumer 의 메세지 전달 역할을 하는 매개체입니다.
MQ의 송신자와 수신자는 다양한 표현으로 설명될 수 있습니다.
송신자 (보내는 쪽) | 수신자 (받는 쪽) |
---|---|
Sender | Receiver |
Producer | Consumer |
Publisher | Subscriber |
MQ의 특징
특징 | 설명 |
---|---|
비동기(Asynchronous) | Queue에 넣어두기 때문에 나중에 처리할 수 있다. |
분리 또는 비동조(Decoupling) | 애플리케이션과 분리할 수 있다. |
탄력성(Resilience) | 일부가 실패 시 전체에 영향을 받지 않는다. |
과잉(Redundancy) | 실패 할 경우 재실행이 가능하다. |
보증(Guarantees) | 작업이 처리된 걸 확인할 수 있다. |
확장성(Scalable) | 다수의 프로세스들이 큐에 메시지를 보낼 수 있다. |
MOM을 위한 표준 응용 계층 프로토콜입니다. AMQP의 정의 기능들은 메시지 지향, 큐잉, 라우팅, 신뢰성 보안입니다.
과거의 미들웨어 표준들은 API 레벨(ex. JMS)에서 등장하였으나 여러 구현체 간 상호 운용성을 제공하지 않아 구현체간 지원이 불가했습니다.
그래서, 서로 다른 시스템들 간의 최대한 효율적인 방법으로 메세지를 교환하기 위해 AMQP 프로토콜이 등장하게 되었습니다.
JMS는 자바 기반의 MOM API이며, 둘 이상의 클라이언트 간에 메세지를 서로 주고 받을 수 있는 기능을 지원합니다.
MQTT(Message Queueing Telemetry Trasport)
는 ISO 표준 (ISO/IEC PRF 20922) 발행-구독 모델 기반의 메시징 프로토콜입니다.
MQTT는 IoT 혹은 대규모 트래픽과 같은 네트워크 대역폭이 제한되는 원격 통신을 위해 만들어진 프로토콜로 TCP/IP 프로토콜 위에서 동작합니다.
연결지향적: MQTT 브로커와 연결을 요청하는 클라이언트는 TCP/IP 소켓 연결을 한 후, 명시적으로 연결을 끊거나 네트워크 사정에 의해 연결이 끊어질 때까지 상태를 유지합니다.
브로커
를 통한 통신: MQTT의 발행-구독 메시징 패턴은 오로지 브로커를 통해서만 통신할 수 있습니다. 개설된 Topic에 메시지를 발행하면 해당 Topic을 구독하는 클라이언트들에게 메시지를 발행할 수 있습니다. (1:1, 1:N 통신 가능)
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+ActiveMQ는 메세지 브로커로 메시지 서버로 이해하시면 됩니다. 즉, 서버를 설치하고 실행해야 한다는 것이지요.
ActiveMQ 공식홈페이지에서 다운로드 받을 수 있습니다.
ActiveMQ 설치
받은 압축파일을 해제하여 설치 디렉터리로 만듭니다.
bin
> activemq.bat
bin
> win64
| win32
> InstallService.bat
ActiveMQ 기본 Port
ActiveMQ는 기본적으로 두가지 포트(61616
, 8161
)를 갖고 있습니다. 61616은 broker로 사용되고, 8161은 웹 관리 콘솔로 사용됩니다.
ActiveMQ가 정상적으로 실행되었다면, http://localhost:8161 로 웹 관리 콘솔에 접속할 수 있습니다.
해당 콘솔을 통해 ActiveMQ 의 Producer, Consumer, Queue, Topic 등 다양한 정보를 편리하게 확인할 수 있습니다.
ActiveMQ는 큐(Queue)
와 토픽(Topic)
이라는 메시지 전달 방식을 지원합니다.
Queue
: 1:1, 메시지를 수신 대기 중인 클라이언트 중 하나에게 전달하는 방식Topic
: 1:N, 메시지를 여러 구독자에게 전달하는 방식Spring에서 ActiveMQ
클라이언트를 구현하기 앞서 필요한 개념을 먼저 살펴보겠습니다.
ActiveMQ는 JMS를 기반으로 통신을 제어하는 메시지 큐입니다.
JMS의 주요 개념
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 메시지를 주고받을 수 있습니다.
application.yml
파일에 사용할 설정 값을 입력합니다.
spring:
activemq:
broker-url: tcp://localhost:61616 # ActiveMQ Broker URL
user: admin # ActiveMQ 웹 관리 콘솔 아이디
password: admin # ActiveMQ 웹 관리 콘솔 비밀번호
activemq:
queue:
name: sample-queue # 사용할 Queue 이름
// 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();
}