Kurs Java

Co to jest Spring AMQP i RabbitMQ?

W bieżącym artykule przedstawiam najważniejsze aspekty projektu Spring AMQP. Nie jest to poradnik o korzystaniu z dobrodziejstw AMQP, tylko raczej zajawienie dobrego pomysłu na rozpoczęcie przygody z kolejkami (i nie tylko) w Springu. Jeśli szukasz wygodnego i nieskomplikowanego rozwiązania w tym obszarze, Spring AMQP może być strzałem w dziesiątkę.

Projekt Spring AMQP stosuje podstawowe koncepcje Springa do opracowywania rozwiązań komunikacyjnych opartych na AMQP.
Appa Notka. AMQP to otwarta standardowa specyfikacja do asynchronicznej komunikacji komunikatów. Innymi słowy, jest to zaawansowany protokół kolejkowania wiadomości. Zawiera opis, jak należy skonstruować wiadomość.
Spring AMQP zapewnia „szablon” (template) jako abstrakcję do wysyłania i odbierania wiadomości. Umożliwia również obsługę POJO sterowanych komunikatami (Message-driven POJOs) z „kontenerem nasłuchującym”. Wszystko dzieje się z wykorzystaniem wstrzykiwania zależności i konfiguracji deklaratywnej.

Projekt składa się z dwóch części, gdzie spring-amqp to podstawowa abstrakcja, a spring-rabbit to implementacja RabbitMQ.
AngularPic
Appa Notka. RabbitMQ to oprogramowanie opensource umożliwiające wymianę wiadomości (exchange), między innymi za pomocą kolejek (queues). Czym jest kolejka? Rozwiązanie polegające na asynchronicznej wymianie komunikatów pomiędzy producentem a klientem (consumer). Dzieje się to za pośrednictwem serwera kolejek (broker wiadomości).

Asynchroniczność, w skrócie, polega na tym, że samo wysłanie wiadomości na kolejkę wcale nie oznacza jej automatycznego przetworzenia (i np. zapisania danych). Dzieje się to dopiero wtedy, gdy konsument jest dostępny i odbiera dane z kolejki. Dzięki temu nawet jeśli konsument przez jakiś czas nie działa, żadne dane nie zostają utracone. Po pojawieniu się odbiorcy dane zostają do niego wysłane. W przypadku gdy było wiele komunikatów, ich kolejność jest zachowywana (to jest podstawowy wariant - trzeba pamiętać, że kolejność zależy też od typu kolejki).

Istotne pojęcia

W kontekście kolejek przewija się zwykle kilka pojęć, które warto znać, aby lepiej rozumieć takie rozwiązania.
  • Queue – kolejka przechowująca komunikaty
  • Exchange - obsługuje zadania wymiany wiadomości
  • Message - komunikat wysyłany na kolejkę przez producenta, który następnie jest odbierany przez konsumenta
  • Routing key - adres komunikatu
Oczywiście elementy te znajdujemy również w omawianym RabbitMQ.

Podstawowe elementy Spring AMQP

Spring AMQP składa się z trzech zasadniczych elementów:
  • Kontener nasłuchujący do asynchronicznego przetwarzania wiadomości przychodzących
  • RabbitTemplate do wysyłania i odbierania wiadomości
  • RabbitAdmin do automatycznego deklarowania kolejek, wymian i wiązań

Konfiguracja

Przykładowa klasa konfiguracyjna jest pokazana na Springowym Githubie:
@Configuration
public class HelloWorldConfiguration {

    protected final String helloWorldQueueName = "hello.world.queue";

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        return connectionFactory;
    }

    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        // Klucz routingu jest ustawiony na nazwę kolejki
        template.setRoutingKey(this.helloWorldQueueName);
        // Miejsce, z którego będziemy odbierać wiadomości
        template.setDefaultReceiveQueue(this.helloWorldQueueName);
        return template;
    }

    @Bean
    // Tworzymy nową beana nowej kolejki
    public Queue helloWorldQueue() {
        return new Queue(this.helloWorldQueueName);
    }
}
Konfiguracja kontenera nasłuchującego:
@Configuration
public class ConsumerConfiguration extends HelloWorldConfiguration {

    @Bean
    public SimpleMessageListenerContainer listenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory());
        container.setQueueNames(this.helloWorldQueueName);
        container.setMessageListener(new MessageListenerAdapter(new HelloWorldHandler()));
        return container;
    }
}
Konfiguracja producenta wiadomości:
@Configuration
public class ProducerConfiguration {

    protected final String helloWorldQueueName = "hello.world.queue";

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setRoutingKey(this.helloWorldQueueName);
        return template;
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        return connectionFactory;
    }

    @Bean
    public ScheduledProducer scheduledProducer() {
        return new ScheduledProducer();
    }

    @Bean
    public BeanPostProcessor postProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }


    static class ScheduledProducer {

        @Autowired
        private volatile RabbitTemplate rabbitTemplate;

        private final AtomicInteger counter = new AtomicInteger();

        @Scheduled(fixedRate = 3000)
        public void sendMessage() {
            rabbitTemplate.convertAndSend("Hello World " + counter.incrementAndGet());
        }
    }
}

Wysyłanie i odbieranie wiadomości

Samo wysłanie wiadomości jest bardzo proste:
rabbitTemplate.convertAndSend("myQueue", "Hello, world!");
Podobnie jest z odbieraniem wiadomości:
@RabbitListener(queues = "myQueue")
public void listen(String in) {
    System.out.println("Message read from myQueue : " + in);
}

Maven Dependency

Oczywiście podstawą do używania rozwiązań Spring AMQP jest wykorzystanie zależności:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
        <version>X.Y.Z.RELEASE</version>
    </dependency>
</dependencies>
Podsumowanie
W rozdziale przedstawiłem ogólny opis Spring AMQP oraz kilka podstawowych elementów kodu z wykorzystaniem tego rozwiązania. Mam nadzieję, że temat zainteresował Cię na tyle, aby przyjrzeć się mu nieco bliżej. Przypominam, że pełny kod źródłowy jest dostępny w projekcie na GitHub-ie.
Autor: Jarek Klimas
Data: 04 grudnia 2021
Labele:Backend, Poziom średniozaawansowany, Java, Spring, Kolejki Linki:
https://spring.io/projects/spring-amqp#overview
https://github.com/spring-projects/spring-amqp-samples
https://www.rabbitmq.com
Masz swoje przemyślenia na temat artykułu? Podziel się nimi!
Masz pytanie odnośnie zagadnienia omawianego w artykule?
Coś, co napisaliśmy, nie zaspokoiło Twojego głodu wiedzy?
Daj nam znać co myślisz i skomentuj artykuł na facebooku!

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy: stackshare
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .


Pozycjonowanie stron: Grupa TENSE