개요
퍼블리셔-서브스크라이버 패턴은 메시지 큐 시스템에서 많이 사용되는 디자인 패턴입니다. 이 패턴은 메시지를 생성하고 발행하는 퍼블리셔와 해당 메시지를 구독하고 수신하는 서브스크라이버로 구성됩니다. ActiveMQ와 RabbitMQ는 두 가지 인기있는 메시지 큐 시스템이며, 모두 퍼블리셔-서브스크라이버 패턴을 지원합니다.
ActiveMQ
ActiveMQ는 오픈 소스 메시지 브로커로, 자바 기반의 메시지 큐 시스템입니다. ActiveMQ는 Java Message Service (JMS) API를 통해 퍼블리셔-서브스크라이버 패턴을 구현합니다. 퍼블리셔는 메시지를 생성하고 ActiveMQ 브로커에 전송합니다. 서브스크라이버는 ActiveMQ 브로커에서 메시지를 받아와 처리합니다.
예제 코드
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ActiveMQExample {
private static final String BROKER_URL = "tcp://localhost:61616";
private static final String QUEUE_NAME = "exampleQueue";
public static void main(String[] args) {
try {
// Connection 생성
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(BROKER_URL);
Connection connection = connectionFactory.createConnection();
connection.start();
// Session 생성
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Producer 생성
MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
// 메시지 생성 및 발행
TextMessage message = session.createTextMessage("Hello, ActiveMQ!");
producer.send(message);
System.out.println("메시지 발행: " + message.getText());
// Consumer 생성
MessageConsumer consumer = session.createConsumer(session.createQueue(QUEUE_NAME));
// 메시지 수신
Message receivedMessage = consumer.receive();
if (receivedMessage instanceof TextMessage) {
System.out.println("메시지 수신: " + ((TextMessage) receivedMessage).getText());
}
// 연결 종료
session.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
RabbitMQ
RabbitMQ는 Erlang으로 구현된 오픈 소스 메시지 브로커입니다. RabbitMQ는 AMQP (Advanced Message Queuing Protocol)를 기반으로 퍼블리셔-서브스크라이버 패턴을 구현합니다. 퍼블리셔는 메시지를 생성하고 RabbitMQ 브로커에게 전송합니다. 서브스크라이버는 RabbitMQ 브로커에서 메시지를 받아와 처리합니다.
예제 코드
import com.rabbitmq.client.*;
import java.io.IOException;
public class RabbitMQExample {
private static final String QUEUE_NAME = "exampleQueue";
public static void main(String[] args) throws IOException, InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setUsername("guest");
factory.setPassword("guest");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// Producer
String message = "Hello, RabbitMQ!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("메시지 발행: " + message);
// Consumer
channel.basicConsume(QUEUE_NAME, true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String receivedMessage = new String(body, "UTF-8");
System.out.println("메시지 수신: " + receivedMessage);
}
});
Thread.sleep(1000);
channel.close();
connection.close();
}
}
결론
ActiveMQ와 RabbitMQ는 메시지 큐 시스템에서 퍼블리셔-서브스크라이버 패턴을 구현하는 데 이용됩니다. 이러한 패턴을 사용하면 분산 환경에서 메시지 기반의 커뮤니케이션을 구현할 수 있으며, 시스템 간의 결합도를 낮추고 확장성과 유연성을 향상시킬 수 있습니다. ActiveMQ와 RabbitMQ는 각각 JMS와 AMQP를 통해 퍼블리셔-서브스크라이버 패턴을 지원하므로, 리소스 및 성능 요구에 따라 선택할 수 있습니다.
참고 문서
- ActiveMQ: https://activemq.apache.org/
- RabbitMQ: https://www.rabbitmq.com/
- JMS: https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html
- AMQP: https://www.amqp.org/