Pemesejan PubSub dengan Spring Data Redis

1. Gambaran keseluruhan

Dalam artikel kedua dari siri yang meneroka Spring Data Redis ini, kita akan melihat barisan mesej / sub mesej.

Di Redis, penerbit tidak diprogramkan untuk mengirim mesej mereka kepada pelanggan tertentu. Sebaliknya, mesej yang diterbitkan dicirikan ke dalam saluran, tanpa mengetahui apa (jika ada) pelanggan yang mungkin ada.

Begitu juga, pelanggan menyatakan minatnya dalam satu atau lebih topik dan hanya menerima mesej yang menarik, tanpa mengetahui apa (jika ada) penerbit di sana.

Perebutan penerbit dan pelanggan ini dapat memungkinkan skalabiliti yang lebih besar dan topologi rangkaian yang lebih dinamik.

2. Konfigurasi Redis

Mari mula menambah konfigurasi yang diperlukan untuk barisan mesej.

Pertama, kami akan menentukan kacang MessageListenerAdapter yang mengandungi pelaksanaan khusus antara muka MessageListener yang disebut RedisMessageSubscriber . Kacang ini bertindak sebagai pelanggan dalam model pesanan pub-sub:

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

RedisMessageListenerContainer adalah kelas yang disediakan oleh Spring Data Redis yang menyediakan tingkah laku tidak segerak untuk pendengar mesej Redis. Ini dipanggil secara dalaman dan, menurut dokumentasi Spring Data Redis - "menangani perincian tahap rendah untuk mendengar, menukar dan menghantar mesej."

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

Kami juga akan membuat kacang menggunakan antara muka MessagePublisher yang dibina khas dan pelaksanaan RedisMessagePublisher . Dengan cara ini, kita dapat memiliki API penerbitan pesan umum, dan meminta pelaksanaan Redis mengambil redisTemplate dan topik sebagai argumen pembangun:

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

Akhirnya, kami akan menetapkan topik yang mana penerbit akan menghantar mesej, dan pelanggan akan menerimanya:

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

3. Menerbitkan Mesej

3.1. Mendefinisikan Muka Muka Penerbit

Spring Data Redis tidak menyediakan antara muka MessagePublisher untuk digunakan untuk pengedaran mesej. Kita dapat menentukan antara muka khusus yang akan menggunakan redisTemplate dalam pelaksanaan:

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

3.2. Pelaksanaan RedisMessagePublisher

Langkah kami selanjutnya adalah menyediakan implementasi antara muka MessagePublisher , menambahkan perincian penerbitan mesej dan menggunakan fungsi-fungsi di redisTemplate.

Templat ini mengandungi sekumpulan fungsi yang sangat kaya untuk pelbagai operasi - di mana convertAndSend mampu menghantar mesej ke barisan melalui topik:

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); } } 

Seperti yang anda lihat, pelaksanaan penerbit adalah mudah. Ia menggunakan kaedah convertAndSend () dari redisTemplate untuk memformat dan menerbitkan mesej yang diberikan ke topik yang dikonfigurasi.

Topik melaksanakan semantik penerbitan dan langganan: apabila mesej diterbitkan, topik ini akan dilampirkan kepada semua pelanggan yang terdaftar untuk mendengarkan topik tersebut.

4. Melanggan Mesej

RedisMessageSubscriber mengimplementasikan antara muka MessageListener yang disediakan oleh 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()); } }

Perhatikan bahawa ada parameter kedua yang disebut corak , yang belum kita gunakan dalam contoh ini. Dokumentasi Spring Data Redis menyatakan bahawa parameter ini mewakili, "pola yang sesuai dengan saluran (jika ditentukan)", tetapi boleh menjadi nol .

5. Menghantar dan Menerima Mesej

Sekarang kita akan mengumpulkan semuanya. Mari buat mesej dan kemudian terbitkan menggunakan RedisMessagePublisher :

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

Ketika kita memanggil penerbitan (pesan) , konten dikirim ke Redis, di mana ia disalurkan ke topik antrean pesan yang ditentukan dalam penerbit kami. Kemudian diedarkan kepada pelanggan topik tersebut.

Anda mungkin sudah menyedari bahawa RedisMessageSubscriber adalah pendengar, yang mendaftarkan dirinya ke barisan untuk mendapatkan semula mesej.

Semasa kedatangan mesej, kaedah onMessage () yang ditentukan pelanggan dicetuskan.

Dalam contoh kami, kami dapat mengesahkan bahawa kami telah menerima mesej yang telah diterbitkan dengan memeriksa messageList di RedisMessageSubscriber kami :

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

6. Kesimpulannya

Dalam artikel ini, kami memeriksa implementasi antrian pesan pub / sub menggunakan Spring Data Redis.

Pelaksanaan contoh di atas boleh didapati dalam projek GitHub.