Redis(spring data redis)パブリッシュ購読pub/sub

6416 ワード

Spring DataはRedisに専用のメッセージ統合を提供し、機能は類似しており、Spring FrameworkのJMS統合と命名されています.
Redisメッセージは、大きく2つの機能領域に分けられます.
  • 公開または生産メッセージ
  • 購読または消費メッセージ
  • 通常、パブリケーション/サブスクリプションモードと呼ばれます.RedisTemplateクラスはメッセージを生成するために使用されます.Spring Dataは、Java EEのようなメッセージ駆動bean形式の非同期受信に対して、メッセージ駆動のPOJO(MDP)を作成するための専用のメッセージリスナーコンテナと、受信を同期するためのRedisConnection を提供する.
    org.springframework.data.redis.接続とorg.springframework.data.redis.Listenerの2つのパケットはredisメッセージのコア機能を提供します.
    1リリース(メッセージ送信)
    メッセージをパブリッシュするには、他の操作と同様に、低レベルRedisConnectionまたは高レベルRedisTemplateを使用します.両方のエンティティは、メッセージおよびターゲットチャネルをパラメータとして受け入れるpublishメソッドを提供する.RedisConnectionは元のデータ(バイト配列)を必要とするが、RedisTemplateは、次の例に示すように、任意のオブジェクトをメッセージとして送信することを可能にする.
    // send message through connection RedisConnection con = ...
    byte[] msg = ...
    byte[] channel = ...
    con.publish(msg, channel); // send message through RedisTemplate
    RedisTemplate template = ...
    template.convertAndSend("hello!", "world");

    2購読(メッセージ受信)
    受信者では、直接名前を付けるか、モードマッチングを使用して1つ以上のチャネルを購読できます.後者の方法は、1つのコマンドを使用して複数のサブスクリプションを作成するだけでなく、モードに一致する限り、サブスクリプション時に作成されていないチャネルをリスニングすることもできます.
    低レベルのRedisConnection を使用すると、Redisコマンドをマッピングする方法subscribeおよびpSubscribeが提供され、それぞれチャネルまたはモードで購読される.パラメータとして複数のチャネルまたはモードを使用できることに注意してください.接続のサブスクリプションまたはクエリーがリスニングされているかどうかを変更するには、RedisConnectiongetSubscriptionメソッドとisSubscribedメソッドを指定します.
    Spring Data Redisの購読コマンドはブロックされています.すなわち、subscribeの接続アップグレードでは、メッセージの待機開始時に現在のスレッドがブロックされます.スレッドは、同じ接続上の別のスレッドがunsubscribeまたはpUnsubscribeを呼び出してサブスクリプションをキャンセルした場合にのみ解放されます.この問題の解決策については、「Message Listener Container」(このドキュメントの後述)を参照してください.したがって、1つの接続でサブスクリプションを開始すると、接続はメッセージの受信を待機し始め、新しいサブスクリプション、既存のサブスクリプションの変更、またはサブスクリプションのキャンセルなどのコマンドしか実行できません.
    メッセージを購読する場合は、MessageListenerのコールバックが必要です.メッセージを受信すると、コールバックとonMessageのコードが実行されます.このインタフェースは、実際のメッセージだけでなく、受信したチャネルにもアクセスし、チャネルをマッチングするためのモード(ある場合)にサブスクリプションすることができます.これにより、呼び出された側は、コンテンツによって様々なメッセージを区別するだけでなく、他の詳細を確認することもできる.
    2.1 Message Listener Containersメッセージリスナーコンテナ
    ブロッキングの性質のため、各リスナーに接続とスレッド管理を提供する必要があるため、低レベル(接続)サブスクリプションは魅力的ではありません.この問題を緩和するために、Spring DataはRedisMessageListenerContainer のすべての煩雑な作業を提供しています.EJBとJMSに詳しい場合は、Spring Frameworkとそのメッセージ駆動POJO(MDP)のサポートにできるだけ近いように設計されているため、よく知っている概念を見つける必要があります.
    RedisMessageListenerは、redisチャネル内のメッセージを受信し、注入されたMessageListenerインスタンスを駆動するメッセージリスニングコンテナとして使用される.このコンテナは、メッセージ受信のすべてのスレッドを担当し、進行中のリスナーに配布されます.メッセージリスナーコンテナは、MDPとメッセージングプロバイダとの間の仲介であり、メッセージ、リソースの取得と解放、異常変換などを受信するために登録されます.これにより、アプリケーション開発者として、受信メッセージに関連付けられた(複雑な可能性がある)ビジネスロジックを作成し、テンプレートRedisインフラストラクチャの関心をフレームワークに委任できます.
    さらに、アプリケーションの占有スペースを最小限に抑えるために、RedisMessageListenerContainerは、複数のリスナーがサブスクリプションを共有しなくても、複数のリスナーが1つの接続と1つのスレッドを共有することを可能にする.したがって、アプリケーションが複数のリスナーまたはチャネルを追跡しても、ランタイムコストはライフサイクル全体で変わらない.さらに、コンテナでは、再起動せずにアプリケーションの実行時にリスナーを追加または削除できるように、実行時構成を変更できます.さらに、コンテナは遅延購読方法を使用し、RedisConnectionは必要に応じてのみ使用される.すべてのリスナーがサブスクリプションをキャンセルした場合、自動的にクリーンアップが実行され、スレッドが解放されます.
    メッセージの非同期性を支援するために、コンテナは、メッセージを割り当てるためにjava.util.concurrent.Executor(またはSpring TaskExecutor)を必要とする.負荷、リスナーの数、またはランタイム環境に応じて、実行プログラムを変更または調整して、ニーズをよりよく満たす必要があります.特に、アプリケーションサーバなどの管理環境では、実行時を利用するために適切なTaskExecutor方式を選択することを強く推奨します.
    2.2 MessageListenerAdapter  MessageListenerAdapterクラスはSpringの非同期サポートメッセージの最後のコンポーネントである.簡単に言えば、いくつかの制約にもかかわらず、ほとんどのクラスをMDPに暴露できます.次のインタフェース定義を考慮してください.
    public interface MessageDelegate {
      void handleMessage(String message);
      void handleMessage(Map message); void handleMessage(byte[] message);
      void handleMessage(Serializable message);
      // pass the channel/pattern as well
      void handleMessage(Serializable message, String channel);
     }

    インタフェースはMessageListenerインタフェースを拡張しないが、MessageListenerAdapterクラスを使用してMDPとして使用することができることに注意してください.また、様々なメッセージ処理方法をどのように使用するかは、強いタイプのコンテンツに応じて異なるMessageであり、彼らはタイプを受信し、処理することができることに注意しなければならない.さらに、メッセージを送信するチャネルまたはモードは、タイプの2番目のパラメータとして方法Stringに渡され得る.
    public class DefaultMessageDelegate implements MessageDelegate {
      // implementation elided for clarity...
    }

    上記のMessageDelegateインターフェース実装(上記のDefaultMessageDelegateクラス)は、Redis依存性が全くないことに留意されたい.POJOをMDPに変換するには、次の構成を使用します.
    
     
    
    
    
      
      
    
    
    
     ...
    

    注意:リスナーtopicは、チャネル(例えば、topic="chatroom")またはモード(例えば、topic="*room")であってもよい
    前の例では、Redisネーミングスペースを使用してメッセージリスナーコンテナを宣言し、POJOをリスナーとして自動的に登録します.完全なbean定義は次のとおりです.
    
      
        
      
    
    
    
      
      
        
          
            
              
            
          
        
      
    

    メッセージを受信するたびに、アダプタはRedisSerializerの低レベルフォーマットと必要なオブジェクトタイプとの間の変換を自動的に透過的に実行します(構成済みを使用します).メソッド呼び出しによる例外は、コンテナによって取得および処理されます(デフォルトでは、例外が記録されます).