Spring Data Redisを使用したPubSubメッセージング
1. 概要
Spring Data Redisを探るシリーズのこの2番目の記事では、pub / subメッセージキューについて説明します。
Redisでは、パブリッシャーは特定のサブスクライバーにメッセージを送信するようにプログラムされていません。 むしろ、パブリッシュされたメッセージは、チャンネルに特徴付けられており、サブスクライバー(存在する場合)の知識はありません。
同様に、サブスクライバーは1つ以上のトピックに関心を示し、関心のあるメッセージのみを受信します。パブリッシャーが(もしあれば)パブリッシャーの知識はありません。
パブリッシャーとサブスクライバーのこの分離により、スケーラビリティが向上し、ネットワークトポロジがより動的になります。
2. Redis設定
メッセージキューに必要な構成の追加を始めましょう。
最初に、RedisMessageSubscriberと呼ばれるMessageListenerインターフェースのカスタム実装を含むMessageListenerAdapterBeanを定義します。 このBeanは、pub-subメッセージングモデルでサブスクライバーとして機能します。
@Bean
MessageListenerAdapter messageListener() {
return new MessageListenerAdapter(new RedisMessageSubscriber());
}
RedisMessageListenerContainerは、Spring Data Redisによって提供されるクラスであり、Redisメッセージリスナーに非同期動作を提供します。 これは内部的に呼び出され、Spring Data Redis documentationによると、「リスニング、変換、およびメッセージディスパッチの低レベルの詳細を処理します」。
@Bean
RedisMessageListenerContainer redisContainer() {
RedisMessageListenerContainer container
= new RedisMessageListenerContainer();
container.setConnectionFactory(jedisConnectionFactory());
container.addMessageListener(messageListener(), topic());
return container;
}
また、カスタムビルドのMessagePublisherインターフェースとRedisMessagePublisher実装を使用してBeanを作成します。 このようにして、汎用のメッセージ発行APIを使用し、Redis実装にコンストラクター引数としてredisTemplateとtopicを使用させることができます。
@Bean
MessagePublisher redisPublisher() {
return new RedisMessagePublisher(redisTemplate(), topic());
}
最後に、発行者がメッセージを送信し、サブスクライバーがメッセージを受信するトピックを設定します。
@Bean
ChannelTopic topic() {
return new ChannelTopic("messageQueue");
}
3. メッセージの公開
3.1. MessagePublisherインターフェースの定義
Spring Data Redisは、メッセージ配信に使用されるMessagePublisherインターフェースを提供していません。 実装でredisTemplateを使用するカスタムインターフェイスを定義できます。
public interface MessagePublisher {
void publish(String message);
}
3.2. RedisMessagePublisherの実装
次のステップは、MessagePublisherインターフェースの実装を提供し、メッセージ公開の詳細を追加し、redisTemplate.の関数を使用することです。
テンプレートには、さまざまな操作のための非常に豊富な関数のセットが含まれています。そのうち、convertAndSendは、トピックを介してキューにメッセージを送信できます。
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);
}
}
ご覧のとおり、パブリッシャーの実装は簡単です。 redisTemplateのconvertAndSend()メソッドを使用して、指定されたメッセージをフォーマットし、構成されたトピックに公開します。
トピックはパブリッシュおよびサブスクライブのセマンティクスを実装します。メッセージがパブリッシュされると、そのトピックでリッスンするように登録されているすべてのサブスクライバーに送信されます。
4. メッセージの購読
RedisMessageSubscriberは、Spring Data Redisが提供するMessageListenerインターフェースを実装します。
@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());
}
}
この例では使用していないpatternという2番目のパラメーターがあることに注意してください。 Spring Data Redisのドキュメントには、このパラメーターは「チャネルに一致するパターン(指定されている場合)」を表すと記載されていますが、nullにすることもできます。
5. メッセージの送受信
次に、すべてをまとめます。 メッセージを作成してから、RedisMessagePublisherを使用して公開しましょう。
String message = "Message " + UUID.randomUUID();
redisMessagePublisher.publish(message);
publish(message)を呼び出すと、コンテンツはRedisに送信され、パブリッシャーで定義されたメッセージキュートピックにルーティングされます。 次に、そのトピックのサブスクライバーに配布されます。
RedisMessageSubscriberがリスナーであり、メッセージを取得するためにキューに登録されていることにお気づきかもしれません。
メッセージの到着時に、定義されたサブスクライバーのonMessage()メソッドがトリガーされました。
この例では、RedisMessageSubscriberのmessageListをチェックすることで、公開されたメッセージを受信したことを確認できます。
RedisMessageSubscriber.messageList.get(0).contains(message)
6. 結論
この記事では、Spring Data Redisを使用したpub / subメッセージキューの実装を検証しました。
上記の例の実装は、a GitHub projectにあります。