Redis のパブリッシュとサブスクライブ
パブリッシュとサブスクライブ:メッセージ パブリッシャーはメッセージをパブリッシュし、メッセージ サブスクライバーはメッセージを受信します。この 2 つは何らかの媒体を通じて接続されます。
たとえば、雑誌を定期購読すると、毎月 1 冊が発行されます。発売すると、配達員は雑誌が届くときに中身を見ることができます。雑誌はご購読いただいた場合のみお届けします
Redis のパブリッシュおよびサブスクライブ (pub/sub) はメッセージ通信モデルです。送信者 (パブ) がメッセージを送信し、サブスクライバー (サブスクリプション) がメッセージを受信します。
Redis クライアントは任意の数のチャネルをサブスクライブできます。
メッセージ グラフの購読/公開:
図からわかるように、必要なものは次のとおりです。
- メッセージ送信者、2. チャネル、3. メッセージ購読者
パブリッシュ・サブスクライブ・メカニズム
- クライアントが
PUBLISH
コマンドを通じてサブスクライバーにメッセージをパブリッシュする場合、クライアントはパブリッシャーと呼ばれます。publisher
subscribe
クライアントがまたは経由でメッセージを受信するとPSUBSCRIBE
、そのクライアントはサブスクライバと呼ばれます。subscriber
- パブリッシャーとサブスクライバー間の関係を切り離すために、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
リスニングコンテナを作成する
@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","测试:消息发布者发布消息");
}
}
試験結果
-
アダプターモード
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(); }