«1. Обзор
Разделение программных компонентов — одна из наиболее важных частей разработки программного обеспечения. Одним из способов достижения этого является использование систем обмена сообщениями, которые обеспечивают асинхронный способ связи между компонентами (сервисами). В этой статье мы рассмотрим одну из таких систем: RabbitMQ.
RabbitMQ — это брокер сообщений, реализующий протокол Advanced Message Queuing Protocol (AMQP). Он предоставляет клиентские библиотеки для основных языков программирования.
Помимо использования для разделения программных компонентов, RabbitMQ можно использовать для:
-
Выполнения фоновых операций Выполнения асинхронной операции
2. Модель обмена сообщениями
Сначала давайте быстро и подробно рассмотрим, как работает обмен сообщениями.
Проще говоря, есть два типа приложений, взаимодействующих с системой обмена сообщениями: производители и потребители. Производители — это те, кто отправляет (публикации) сообщения брокеру, и потребители, которые получают сообщения от брокера. Обычно эти программы (компоненты программного обеспечения) работают на разных машинах, и RabbitMQ выступает в качестве связующего звена между ними.
В этой статье мы обсудим простой пример с двумя сервисами, которые будут взаимодействовать с помощью RabbitMQ. Одна из служб будет публиковать сообщения в RabbitMQ, а другая — потреблять.
3. Настройка
Для начала запустим RabbitMQ, используя официальное руководство по установке здесь.
Естественно, мы будем использовать Java-клиент для взаимодействия с сервером RabbitMQ; зависимость Maven для этого клиента:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.0</version>
</dependency>
После запуска брокера RabbitMQ с использованием официального руководства нам нужно подключиться к нему с помощью java-клиента:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
Мы используем ConnectionFactory для установки соединения с сервер, он также заботится о протоколе (AMQP) и аутентификации. Здесь мы подключаемся к серверу на локальном хосте, мы можем изменить имя хоста с помощью функции setHost.
Мы можем использовать setPort для установки порта, если порт по умолчанию не используется сервером RabbitMQ; порт по умолчанию для RabbitMQ — 15672:
factory.setPort(15678);
Мы можем установить имя пользователя и пароль:
factory.setUsername("user1");
factory.setPassword("MyPassword");
Далее мы будем использовать это соединение для публикации и потребления сообщений.
4. Производитель
Рассмотрим простой сценарий, в котором веб-приложение позволяет пользователям добавлять новые продукты на веб-сайт. Каждый раз, когда добавляется новый продукт, нам нужно отправить электронное письмо клиентам.
Во-первых, давайте определим очередь:
channel.queueDeclare("products_queue", false, false, false, null);
Каждый раз, когда пользователи добавляют новый продукт, мы публикуем сообщение в очереди:
String message = "product details";
channel.basicPublish("", "products_queue", null, message.getBytes());
Наконец, мы закрываем канал и соединение:
channel.close();
connection.close();
Это сообщение будет использовано другой службой, отвечающей за отправку писем клиентам.
5. Потребитель
Давайте посмотрим, что мы можем реализовать на стороне потребителя; мы собираемся объявить ту же очередь:
channel.queueDeclare("products_queue", false, false, false, null);
Вот как мы определяем потребителя, который будет асинхронно обрабатывать сообщения из очереди:
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(
String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
// process the message
}
};
channel.basicConsume("products_queue", true, consumer);
6. Заключение
В этой простой статье были рассмотрены основные понятия RabbitMQ. и обсудили простой пример с его использованием.
Полную реализацию этого руководства можно найти в проекте GitHub.