JAVA は Redis のパブリッシュとサブスクライブを実装します

Redis のパブリッシュとサブスクライブ

パブリッシュとサブスクライブ:メッセージ パブリッシャーはメッセージをパブリッシュしメッセージ サブスクライバーはメッセージを受信します。この 2 つは何らかの媒体を通じて接続されます。

たとえば、雑誌を定期購読すると、毎月 1 冊が発行されます。発売すると、配達員は雑誌が届くときに中身を見ることができます。雑誌はご購読いただいた場合のみお届けします

Redis のパブリッシュおよびサブスクライブ (pub/sub) はメッセージ通信モデルです。送信者 (パブ) がメッセージを送信し、サブスクライバー (サブスクリプション) がメッセージを受信します。

Redis クライアントは任意の数のチャネルをサブスクライブできます。

メッセージ グラフの購読/公開:

図からわかるように、必要なものは次のとおりです。

  1. メッセージ送信者、2. チャネル、3. メッセージ購読者

パブリッシュ・サブスクライブ・メカニズム

  1. クライアントがPUBLISHコマンドを通じてサブスクライバーにメッセージをパブリッシュする場合、クライアントはパブリッシャーと呼ばれます。publisher
  2. subscribeクライアントがまたは経由でメッセージを受信するとPSUBSCRIBE、そのクライアントはサブスクライバと呼ばれます。subscriber
  3. パブリッシャーとサブスクライバー間の関係を切り離すために、Redis はchannel(频道)両者の間の仲介者としてチャネルを使用します。パブリッシャーはメッセージをチャネルに直接送信し、チャネルはサブスクライバーにメッセージを送信する責任を負います。両者の間には直接の接触はなく、お互いの存在を知りません。

サブスクライバ 1、2、および 3 はチャネル チャネルにサブスクライブします。メッセージがチャネルにパブリッシュされると、メッセージは 3 つのサブスクライバ クライアントに送信されます。

デモの実装

研究参考リンク

依存関係を導入する

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

設定ファイルの追加

spring:
  redis:
    host: 127.0.0.1
    database: 5
    password:
    port: 6379
  1. リスナーモード

リスニングコンテナを作成する

@Configuration
public class CatListenerConfig extends CachingConfigurerSupport {
    
    

    /**
     * 消息监听容器
     *
     * @param factory
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory factory){
    
    
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        //订阅一个通道 该处的通道名是发布消息时的名称
       container.setConnectionFactory(connectionFactory);
        //订阅了一个叫cat 的通道
        container.addMessageListener(catAdapter, new PatternTopic("cat"));
        container.addMessageListener(fishAdapter, new PatternTopic("fish"));
        return container;
    }

    

}
@Component
public class CatListener implements MessageListener {
    
    
    @Override
    public void onMessage(Message message, byte[] bytes) {
    
    
        System.out.println("我是监听者,我监听到的消息是 " + message.toString());
    }
}
package com.maoxs.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * 监听发送的消息
 */
public class FishListener  implements MessageListener  {
    
    

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void onMessage(Message message, byte[] bytes) {
    
    
        System.out.println("我是Fish监听" + message.toString());
    }
}

テストクラスを構築し、リリース監視をテストする

@RestController
public class TestController {
    
    

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @PostMapping("/cat")
    public void test2(){
    
    
        stringRedisTemplate.convertAndSend("cat","测试:消息发布者发布消息");
    }
  
   @PostMapping("/fish")
    public void fish(){
    
    
        stringRedisTemplate.convertAndSend("fish","测试:消息发布者发布消息");
    }
}

試験結果

  1. アダプターモード

    2.1 構成

        /**
         * MessageListenerAdapter 模式
         * 该处topic的 key为bean的name
         * @param connectionFactory
         * @param adapterMap
         * @return
         */
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,Map<String, MessageListenerAdapter> adapterMap) {
          
          
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            adapterMap.keySet().forEach(topic-> container.addMessageListener(adapterMap.get(topic),new PatternTopic(topic)));
            return container;
        }
    

    モニター1

    package com.sst.loan.risk.listener;
    
    import com.sst.loan.risk.manager.RuleLoadManager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * 监听适配器
     *
     * @author 蔡定努
     * @date 2023/06/13 10:26
     */
    @Slf4j
    @Component("ruleRefreshAdapter")
    public class RuleRefreshAdapter  extends MessageListenerAdapter {
          
          
      
    
    
        @Override
        public void onMessage(Message message, byte[] bytes) {
          
          
            log.info(">>>>>>> 消息适配器收到刷新规则的请求 <<<<<<<<<<<<<<");
    
        }
    }
    
    

    モニター2

    package com.sst.loan.risk.listener;
    
    import com.sst.loan.risk.manager.RuleLoadManager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * 监听适配器
     *
     * @author 蔡定努
     * @date 2023/06/13 10:26
     */
    @Slf4j
    @Component("ruleRefreshAdapter2")
    public class RuleRefreshAdapter2  extends MessageListenerAdapter {
          
          
      
    
    
        @Override
        public void onMessage(Message message, byte[] bytes) {
          
          
            log.info(">>>>>>> 消息适配器收到刷新规则的请求 <<<<<<<<<<<<<<");
            
        }
    }
    

    テスト

    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
    
        /**
         * 
         * @author 蔡定努
         */
        @GetMapping("refresh")
        public Object refresh() {
          
          
            stringRedisTemplate.convertAndSend("ruleRefreshAdapter","refresh");
            return Result.success();
        }
        
        
        /**
         * 
         * @author 蔡定努
         */
        @GetMapping("refresh")
        public Object refresh() {
          
          
            stringRedisTemplate.convertAndSend("ruleRefreshAdapter2","refresh");
            return Result.success();
        }
    

おすすめ

転載: blog.csdn.net/caidingnu/article/details/131184710