Spring Data RedisによるPubSubメッセージング

データ]

  • リンク:/tag/redis/[Redis]

1概要

Spring Data Redisを探るシリーズの第2回目のこの記事では、pub/subメッセージ・キューについて見ていきます。

Redisでは、パブリッシャーは特定の購読者にメッセージを送信するようにプログラムされていません。そうではなく、パブリッシュされたメッセージは、(もしあれば)購読者が何であるかについての知識なしに、チャネルに特徴付けられます。

同様に、購読者は1つ以上のトピックに関心を表明し、関心があるメッセージのみを受信します。ただし、パブリッシャが存在する場合はその知識がありません。

パブリッシャとサブスクライバをこのように分離することで、より高いスケーラビリティとより動的なネットワークトポロジが可能になります。

2 Redisの設定

メッセージキューに必要な設定を追加しましょう。

まず、 RedisMessageSubscriber という MessageListener インターフェイスのカスタム実装を含む MessageListenerAdapter Beanを定義します。このBeanは、pub-subメッセージングモデルの加入者として機能します。

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

RedisMessageListenerContainer はSpring Data Redisが提供するクラスで、Redisメッセージリスナーに非同期動作を提供します。これは内部的に呼び出され、http://docs.spring.io/spring-data/data-redis/docs/current/api/org/springframework/data/redis/listener/RedisMessageListenerContainer.html[Spring Data Redis]に従って実行されます。ドキュメンテーション] - 「リスニング、変換、メッセージディスパッチの低レベルの詳細を扱います。」

@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<String, Object> redisTemplate;
    @Autowired
    private ChannelTopic topic;

    public RedisMessagePublisher() {
    }

    public RedisMessagePublisher(
      RedisTemplate<String, Object> 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<String> messageList = new ArrayList<String>();

    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メッセージキューの実装を調べました。

上記の例の実装はhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-redis[GitHubプロジェクト]にあります。