Обмен сообщениями с RabbitMQ
Этот урок освещает процесс настройки RabbitMQ AMQP сервера, который публикует и подписывается на сообщения.
Что вы создадите
Вы создадите приложение, которое публикует сообщение с использованием Spring AMQP
RabbitTemplate
и подписывается на POJO сообщение через
MessageListenerAdapter
.
Что вам потребуется
- Примерно 15 минут свободного времени
- Любимый текстовый редактор или IDE
- JDK 6 и выше
- Gradle 1.11+ или Maven 3.0+
- Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.
- RabbitMQ сервер (инструкция по установке см. ниже)
Как проходить этот урок
Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.
Чтобы начать с нуля, перейдите в Настройка проекта.
Чтобы пропустить базовые шаги, выполните следующее:
- Загрузите и
распакуйте архив с кодом этого урока, либо кнонируйте из репозитория с помощью
Git:
git clone https://github.com/spring-guides/gs-messaging-rabbitmq.git
- Перейдите в каталог
gs-messaging-rabbitmq/initial
- Забегая вперед, cоздайте получателя сообщения RabbitMQ
Когда вы закончите, можете сравнить получившийся результат с образцом в gs-messaging-rabbitmq/complete
.
Настройка проекта
Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.
Создание структуры каталогов
В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру,
командой mkdir -p src/main/java/hello
для *nix систем:
└── src └── main └── java └── hello
Создание файла сборки Gradle
Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.
pom.xml
, вы найдете, что указана версия для maven-compiler-plugin.
В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы,
которая по умолчанию имеет старую(до Java 5) версию этого плагина.
build.gradle
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-release" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.8.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'gs-messaging-rabbitmq'
version = '0.1.0'
}
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/libs-release" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-amqp")
testCompile("junit:junit")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Spring Boot gradle plugin предоставляет множество удобных возможностей:
- Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
- Он ищет
public static void main()
метод, как признак исполняемого класса - Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий
Создание получателя сообщения RabbitMQ
В любом приложении на основе обмена сообщениями вам необходимо создать получателя, который будет реагировать на опубликованные сообщения.
src/main/java/hello/Receiver.java
package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Receiver {
@Autowired
AnnotationConfigApplicationContext context;
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
this.context.close();
}
}
Receiver
является простым POJO, у которого определен метод для получения сообщений.
Когда вы регистрируете его в качестве получателя сообщений, вы можете назвать его
любым именем.
AnnotationConfigApplicationContext
. Это
позволяет ему завершать приложение после получения сообщения. Однако это не желательно
делать в рабочих приложениях.
Регистрация обработчика и отправка сообщения
Spring AMQP RabbitTemplate
предоставляет вам все необходимое для отправки и
получения соoбщений через RabbitMQ. В частности, вам необходимо настроить:
- Контейнер обработчика сообщения
- Описать очередь, систему обмена и взаимодействие между ними
Вы будете использовать RabbitTemplate
для отправки сообщения и зарегистрируете
Receiver
в контейнере обработчика сообщения для получения сообщения. Фабрика
соединения включает в себя оба из них, позволяя им подключаться к RabbitMQ серверу.
src/main/java/hello/Application.java
package hello;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
public class Application implements CommandLineRunner {
final static String queueName = "spring-boot";
@Autowired
RabbitTemplate rabbitTemplate;
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange("spring-boot-exchange");
}
@Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueName);
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
@Bean
Receiver receiver() {
return new Receiver();
}
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Waiting five seconds...");
Thread.sleep(5000);
System.out.println("Sending message...");
rabbitTemplate.convertAndSend(queueName, "Hello from RabbitMQ!");
}
}
Бин, определенный в методе listenerAdapter()
, зарегистрирован как обработчик сообщения в контейнере,
определенном в container()
. Он будет обрабатывать сообщения в очереди "chat". Т.к. Receiver класс
является POJO, его необходимо упаковать в адаптер MessageListenerAdapter
бработчика сообщения, в
котором вы укажете вызов метода receiveMessage()
.
Бины контейнера обработчика сообщения и получателя - это все, что вам необходимо для обработки сообщений. Для отправки сообщения, вам необходим Rabbit шаблон.
Метод queue()
создает AMQP очередь. Метод exchange()
создает список обмена.
Метод binding()
связывает их между собой, определяя их поведение при публикации
RabbitTemplate для обмена.
Queue
, TopicExchange
и Binding
были определены как высокоуровневые Spring бины в правильном порядке их организации.
Метод main()
начинает свою работу с создания контекста приложения Spring. Затем контекст приложения
инициализирует контейнер обработчика сообщения, который в свою очередь запускает прослушку сообщений. Далее он
получает RabbitTemplate
из контекста приложени, ждет пять секунд и отправляет сообщение
"Hello from RabbitMQ!" очередь "chat". В заключении, он закрывает контекст приложения Spring и приложение завершает работу.
Сборка исполняемого JAR
Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.
./gradlew build
Затем вы можете запустить JAR-файл:
java -jar build/libs/gs-messaging-rabbitmq-0.1.0.jar
Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run
,
либо вы можете собрать приложение с mvn clean package
и запустить JAR примерно так:
java -jar target/gs-messaging-rabbitmq-0.1.0.jar
Запуск сервиса
Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:
./gradlew clean build && java -jar build/libs/gs-messaging-rabbitmq-0.1.0.jar
mvn clean package && java -jar target/gs-messaging-rabbitmq-0.1.0.jar
.
Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:
./gradlew bootRun
mvn spring-boot:run
.Вы должны увидеть следующее:
Sending message... Received <Hello from RabbitMQ!>
Итог
Поздравляем! Вы только что разработали простой приложение для публикации и подписки, используя Spring и RabbitMQ. Здесь вы можете сделать большее, чем описано в данном уроке, но он рассчитан стать хорошим стартом для вас.
С оригинальным текстом урока вы можете ознакомиться на spring.io.
comments powered by Disqus