Рубрики
Без рубрики

Весеннее дистанционное управление с помощью JMS и ActiveMQ

Быстрый и практический пример удаленного управления с помощью Spring и JMS.

Автор оригинала: baeldung.

1. Обзор

В предыдущей статье мы видели, как Spring Remoting можно использовать для предоставления RPC поверх асинхронного канала в качестве очереди AMQP . Однако мы также можем получить тот же результат, используя JMS .

В этой статье мы рассмотрим, как настроить удаленный вызов с помощью Spring Remoting JMS и Apache ActiveMQ в качестве промежуточного программного обеспечения для обмена сообщениями.

2. Запуск брокера Apache ActiveMQ

Apache ActiveMQ – это брокер сообщений с открытым исходным кодом, который позволяет приложениям асинхронно обмениваться информацией и полностью совместим со службой сообщений Java API .

Чтобы запустить наш эксперимент, нам сначала нужно настроить запущенный экземпляр ActiveMQ . Мы можем выбрать один из нескольких способов: следуя шагам , описанным в официальном руководстве , встроить его в Java приложение или просто запустить Docker контейнер со следующей командой:

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3

Это запустит контейнер ActiveMQ , который предоставляет на порту 8081 простой веб-интерфейс администрирования, с помощью которого мы можем проверить доступные очереди, подключенные клиенты и другую административную информацию. JMS клиентам потребуется использовать порт 61616 для подключения к брокеру и обмена сообщениями.

3. Зависимости Maven

Как и в предыдущих статьях , посвященных Spring Remoting , мы собираемся настроить сервер и клиент Spring Boot приложения, чтобы показать, как работает JMS Remoting .

Как обычно, мы тщательно выбираем зависимости Spring Boot starter, как описано здесь :


    org.springframework.boot
    spring-boot-starter-activemq
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    

Мы явно исключили spring-boot-starter-tomcat , чтобы не иметь Tomcat связанных .jar файлов в пути к классу.

Это, в свою очередь, предотвратит механизм автоматической настройки Spring Boot для запуска встроенного веб-сервера при запуске приложения, поскольку он нам не нужен.

4. Серверное приложение

4.1. Предоставление Услуг

Мы настроим серверное приложение, которое предоставляет услугу Бронирования такси , которую клиенты смогут вызывать.

Первым шагом является объявление компонента, реализующего интерфейс службы, которую мы хотим предоставить клиентам. Это компонент, который будет выполнять бизнес-логику на сервере:

@Bean 
CabBookingService bookingService() {
    return new CabBookingServiceImpl();
}

Затем давайте определим очередь, из которой сервер будет извлекать вызовы, указав ее имя в конструкторе:

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

Как мы уже знаем из предыдущих статей, одной из основных концепций Spring Remoting является Экспортер услуг , компонент , который собирает запросы на вызов из некоторого источника , в данном случае ApacheMQ queue, и вызывает нужный метод реализации службы.

Для работы с JMS мы определяем JmsInvokerServiceExporter :

@Bean 
JmsInvokerServiceExporter exporter(CabBookingService implementation) {
    JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
    exporter.setServiceInterface(CabBookingService.class);
    exporter.setService(implementation);
    return exporter;
}

Наконец, нам нужно определить слушателя, который несет ответственность за потребление сообщений. Слушатель действует как мост между Apache MQ и JmsInvokerServiceExporter , он прослушивает сообщения вызова, доступные в очереди, пересылает вызов экспортеру службы и сериализует обратно результаты:

@Bean SimpleMessageListenerContainer listener(
  ConnectionFactory factory, 
  JmsInvokerServiceExporter exporter) {
 
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.setDestinationName("remotingQueue");
    container.setConcurrentConsumers(1);
    container.setMessageListener(exporter);
    return container;
}

4.2. Конфигурация

Давайте не забудем настроить файл application.properties , чтобы разрешить Spring Boot настраивать некоторые базовые объекты, такие как, например, ConnectionFactory , необходимый слушателю. Значения различных параметров в основном зависят от способа

Значения различных параметров в основном зависят от способа установки ApacheMQ , и следующая конфигурация является разумной для нашего контейнера Docker , работающего на той же машине, на которой мы будем запускать эти примеры:

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.baeldung.api

Параметр spring.activemq.broker-url является ссылкой на порт AMQ . Вместо этого требуется более глубокое объяснение параметра spring.activemq.packages.trusted|/. Начиная с версии 5.12.2 ActiveMQ по умолчанию отказывается от любого сообщения типа

Начиная с версии 5.12.2 ActiveMQ по умолчанию отклоняет любое сообщение типа Сообщение об объекте , используется для обмена сериализованными Ява объект, потому что в некоторых контекстах он считается потенциальным вектором атаки на безопасность.

Во всяком случае, можно указать AMQ принимать сериализованные объекты в указанных пакетах. org.springframework.remoting.support – это пакет, содержащий основные сообщения, представляющие вызов удаленного метода и его результат. Посылка

Пакет com.baeldung.api содержит параметры и результаты нашего сервиса. java.lang добавляется потому , что объект, представляющий результат бронирования такси, ссылается на строку |, поэтому нам также нужно сериализовать ее.

5. Клиентское приложение

5.1. Вызов удаленной службы

Давайте теперь займемся клиентом. Опять же, нам нужно определить очередь, в которую будут записываться сообщения вызова. Нам нужно дважды проверить, что и клиент, и сервер используют одно и то же имя.

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

Затем нам нужно создать экспортера:

@Bean 
FactoryBean invoker(ConnectionFactory factory, Queue queue) {
    JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean();
    factoryBean.setConnectionFactory(factory);
    factoryBean.setServiceInterface(CabBookingService.class);
    factoryBean.setQueue(queue);
    return factoryBean;
}

Теперь мы можем использовать удаленную службу, как если бы она была объявлена как локальный компонент:

CabBookingService service = context.getBean(CabBookingService.class);
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));

5.2. Запустите пример

Также для клиентского приложения мы должны правильно выбрать значения в файле .properties . В обычной настройке они будут точно соответствовать тем, которые используются на стороне сервера.

Этого должно быть достаточно, чтобы продемонстрировать удаленный вызов через Apache AMQ . Итак, давайте сначала запустим Apache MQ , затем серверное приложение и, наконец, клиентское приложение, которое вызовет удаленную службу.

6. Заключение

В этом кратком руководстве мы увидели, как мы могли бы использовать Spring Remoting для предоставления RPC поверх системы JMS в качестве AMQ .

Spring Remoting продолжает демонстрировать, как легко быстро настроить асинхронный вызов независимо от базового канала.

Как обычно, вы найдете источники на GitHub .