Messaggistica PubSub con Spring Data Redis

1. Panoramica

In questo secondo articolo della serie che esplora Spring Data Redis, daremo uno sguardo alle code di messaggi pub / sub.

In Redis, gli editori non sono programmati per inviare i loro messaggi a sottoscrittori specifici. Piuttosto, i messaggi pubblicati sono caratterizzati in canali, senza sapere quali (se ce ne sono) iscritti potrebbero esserci.

Allo stesso modo, gli abbonati esprimono interesse per uno o più argomenti e ricevono solo messaggi di interesse, senza sapere quali sono gli editori (se ce ne sono).

Questo disaccoppiamento di editori e sottoscrittori può consentire una maggiore scalabilità e una topologia di rete più dinamica.

2. Configurazione Redis

Cominciamo ad aggiungere la configurazione richiesta per le code dei messaggi.

Innanzitutto, definiremo un bean MessageListenerAdapter che contiene un'implementazione personalizzata dell'interfaccia MessageListener chiamata RedisMessageSubscriber . Questo bean funge da abbonato nel modello di messaggistica pub-sub:

@Bean MessageListenerAdapter messageListener() { return new MessageListenerAdapter(new RedisMessageSubscriber()); }

RedisMessageListenerContainer è una classe fornita da Spring Data Redis che fornisce un comportamento asincrono per i listener di messaggi Redis. Questo viene chiamato internamente e, secondo la documentazione di Spring Data Redis, "gestisce i dettagli di basso livello di ascolto, conversione e invio di messaggi".

@Bean RedisMessageListenerContainer redisContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); container.addMessageListener(messageListener(), topic()); return container; }

Creeremo anche un bean utilizzando un'interfaccia MessagePublisher personalizzata e un'implementazione RedisMessagePublisher . In questo modo, possiamo avere un'API di pubblicazione dei messaggi generica e fare in modo che l'implementazione Redis prenda un redisTemplate e un argomento come argomenti del costruttore:

@Bean MessagePublisher redisPublisher() { return new RedisMessagePublisher(redisTemplate(), topic()); }

Infine, imposteremo un argomento a cui l'editore invierà messaggi e l'abbonato li riceverà:

@Bean ChannelTopic topic() { return new ChannelTopic("messageQueue"); }

3. Pubblicazione di messaggi

3.1. Definizione dell'interfaccia MessagePublisher

Spring Data Redis non fornisce un'interfaccia MessagePublisher da utilizzare per la distribuzione dei messaggi. Possiamo definire un'interfaccia personalizzata che utilizzerà redisTemplate nell'implementazione:

public interface MessagePublisher { void publish(String message); }

3.2. RedisMessagePublisher implementazione

Il passaggio successivo consiste nel fornire un'implementazione dell'interfaccia MessagePublisher , aggiungendo i dettagli di pubblicazione dei messaggi e utilizzando le funzioni in redisTemplate.

Il modello contiene un set molto ricco di funzioni per un'ampia gamma di operazioni, di cui convertAndSend è in grado di inviare un messaggio a una coda attraverso un argomento:

public class RedisMessagePublisher implements MessagePublisher { @Autowired private RedisTemplate redisTemplate; @Autowired private ChannelTopic topic; public RedisMessagePublisher() { } public RedisMessagePublisher( RedisTemplate redisTemplate, ChannelTopic topic) { this.redisTemplate = redisTemplate; this.topic = topic; } public void publish(String message) { redisTemplate.convertAndSend(topic.getTopic(), message); } } 

Come puoi vedere, l'implementazione del publisher è semplice. Utilizza il metodo convertAndSend () di redisTemplate per formattare e pubblicare il messaggio specificato nell'argomento configurato.

Un argomento implementa la semantica di pubblicazione e sottoscrizione: quando un messaggio viene pubblicato, viene inviato a tutti i sottoscrittori registrati per ascoltare quell'argomento.

4. Iscrizione ai messaggi

RedisMessageSubscriber implementa l' interfaccia MessageListener fornita da Spring Data Redis :

@Service public class RedisMessageSubscriber implements MessageListener { public static List messageList = new ArrayList(); public void onMessage(Message message, byte[] pattern) { messageList.add(message.toString()); System.out.println("Message received: " + message.toString()); } }

Nota che c'è un secondo parametro chiamato pattern , che non abbiamo usato in questo esempio. La documentazione di Spring Data Redis afferma che questo parametro rappresenta il "modello che corrisponde al canale (se specificato)", ma che può essere nullo .

5. Invio e ricezione di messaggi

Ora metteremo tutto insieme. Creiamo un messaggio e poi pubblichiamo utilizzando RedisMessagePublisher :

String message = "Message " + UUID.randomUUID(); redisMessagePublisher.publish(message);

Quando chiamiamo publish (messaggio) , il contenuto viene inviato a Redis, dove viene instradato all'argomento della coda dei messaggi definito nel nostro editore. Quindi viene distribuito agli abbonati di quell'argomento.

Potresti già aver notato che RedisMessageSubscriber è un listener, che si registra nella coda per il recupero dei messaggi.

All'arrivo del messaggio, è stato attivato il metodo onMessage () dell'abbonato definito.

Nel nostro esempio, possiamo verificare di aver ricevuto messaggi che sono stati pubblicati controllando messageList nel nostro RedisMessageSubscriber :

RedisMessageSubscriber.messageList.get(0).contains(message) 

6. Conclusione

In questo articolo, abbiamo esaminato l'implementazione di una coda di messaggi pub / sub utilizzando Spring Data Redis.

L'implementazione dell'esempio precedente può essere trovata in un progetto GitHub.