【redis】發布訂閱

Redis的發布訂閱(Pub/Sub)是一種基于消息多播的通信機制,它允許消息的**發布者(Publisher)向特定頻道發送消息,而訂閱者(Subscriber)**通過訂閱頻道或模式來接收消息。

其核心特點如下:

  1. 輕量級:無需額外組件,直接通過Redis服務實現

  2. 實時性:消息即時推送,無輪詢延遲

  3. 廣播模式:一個消息可被多個訂閱者同時接收

  4. 無狀態性:不存儲歷史消息,訂閱者只能接收訂閱后的消息

發布訂閱命令的使用

有關發布訂閱的命令可以通過help @pubsub命令來查看。有關命令的使用可以通過help 命令來查看,例如help publish

基礎命令速查表

命令作用示例
SUBSCRIBE訂閱一個或多個頻道SUBSCRIBE news sports
PSUBSCRIBE使用模式匹配訂閱頻道PSUBSCRIBE sensor.*
PUBLISH向指定頻道發送消息PUBLISH news "Hello"
UNSUBSCRIBE退訂指定頻道UNSUBSCRIBE news
PUNSUBSCRIBE退訂模式訂閱PUNSUBSCRIBE sensor.*
PUBSUB CHANNELS查看活躍頻道列表PUBSUB CHANNELS "sensor.*"

操作示例

# 訂閱者A(終端1)
127.0.0.1:6379> subscribe notifications
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "notifications"
3) (integer) 1# 訂閱者B(終端2) 
127.0.0.1:6379> psubscribe system.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "system.*"
3) (integer) 1# 發布消息(終端3)
127.0.0.1:6379> publish notifications "Service will be upgraded soon"
(integer) 1127.0.0.1:6379> publish system.alert "CPU usage exceeds 90%"
(integer) 1# 訂閱者A收到:
1) "message"
2) "notifications"
3) "Service will be upgraded soon"# 訂閱者B收到: 
1) "pmessage"
2) "system.*"
3) "system.alert"
4) "CPU usage exceeds 90%"

發布訂閱的使用場景與優缺點

適用場景

  1. 實時通知系統:用戶在線狀態更新,即時聊天消息推送

  2. 事件驅動架構:緩存失效廣播,分布式配置更新

  3. 輕量級監控:服務器狀態報警,業務指標異常通知

優點

  • 極低延遲(平均<1ms)

  • 支持百萬級TPS消息吞吐

  • 模式匹配訂閱實現靈活路由

  • 零外部依賴(僅需Redis服務)

缺點

消息不可靠性:不保證送達,離線訂閱者會丟失消息

無持久化機制:重啟后所有訂閱關系丟失

客戶端阻塞:訂閱操作會占用連接線程(需異步處理)

替代方案建議:需要可靠消息時,使用Redis Streams(支持消息持久化、消費者組)或RabbitMQ/Kafka

在Java中使用RedisTemplate實現

配置RedisTemplate

package com.morris.redis.demo.pubsub;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** 對redis的鍵值進行序列化*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 使用 String 序列化 keytemplate.setKeySerializer(new StringRedisSerializer());// 使用 JSON 序列化 value(需要額外依賴 jackson)template.setValueSerializer(new GenericJackson2JsonRedisSerializer());// 對于 Hash 結構同理template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}

實現消息發布者

package com.morris.redis.demo.pubsub;import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** 消息發布者*/
@Service
public class MessagePublisher {@Resourceprivate RedisTemplate<String, Object> redisTemplate;public void sendNotification(String channel, String message) {redisTemplate.convertAndSend(channel, message);}
}

實現消息訂閱者

package com.morris.redis.demo.pubsub;import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 消息訂閱者*/
@Component
public class MessageSubscriber implements MessageListener {@Resourceprivate RedisTemplate redisTemplate;@Overridepublic void onMessage(Message message, byte[] pattern) {String channel = new String(message.getChannel());String body = (String) redisTemplate.getValueSerializer().deserialize(message.getBody());System.out.printf("收到頻道[%s]的消息: %s\n", channel, body);}
}

配置訂閱監聽

package com.morris.redis.demo.pubsub;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;/*** 配置redis消息訂閱監聽器*/
@Configuration
@Slf4j
public class RedisPubSubConfig {@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory, MessageSubscriber messageSubscriber) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(factory);// 訂閱具體頻道container.addMessageListener(messageSubscriber, new ChannelTopic("notifications"));// 訂閱模式匹配container.addMessageListener(messageSubscriber, new PatternTopic("system.*"));// 異常處理container.setErrorHandler((e) -> {log.error("[listen message] error ", e);});return container;}
}

使用示例

package com.morris.redis.demo.pubsub;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 使用接口發布消息*/
@RestController
@RequestMapping("/pubsub")
public class PubSubDemoController {@Resourceprivate MessagePublisher publisher;// 發布告警@GetMapping("/alert")public String sendAlert(@RequestParam String message) {publisher.sendNotification("system.alert", message);return "警報已發送";}// 發布通知@GetMapping("/notify")public String sendNotify(@RequestParam String message) {publisher.sendNotification("notifications", message);return "通知已發送";}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72301.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72301.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72301.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言零基礎入門:嵌入式系統開發之旅

C語言零基礎入門&#xff1a;嵌入式系統開發之旅 一、引言 嵌入式系統開發是當今科技領域中一個極具魅力和挑戰性的方向。從智能家居設備到汽車電子系統&#xff0c;從智能穿戴設備到工業自動化控制&#xff0c;嵌入式系統無處不在。而C語言&#xff0c;作為嵌入式開發中最常…

K8S學習之基礎二十三:k8s的持久化存儲之nfs

K8S持久化存儲之nfs ? 在 Kubernetes (k8s) 中使用 NFS&#xff08;Network File System&#xff09;作為存儲解決方案是一種常見的方式&#xff0c;特別是在需要共享存儲的場景中。以下是關于如何在 Kubernetes 中使用 NFS 存儲的詳細說明&#xff1a; 1. 準備 NFS 服務器 …

【Rust】枚舉和模式匹配——Rust語言基礎14

文章目錄 1. 枚舉類型1.2. Option 枚舉 2. match 控制流結構2.1. match 對綁定值的匹配2.2. Option<T> 的匹配2.3. 通配模式以及 _ 占位符 3. if let 控制流4. 小測試 1. 枚舉類型 枚舉&#xff08;enumerations&#xff09;&#xff0c;也被稱作 enums。枚舉允許你通過…

【商城實戰(25)】解鎖UniApp移動端適配秘籍,打造完美商城體驗

【商城實戰】專欄重磅來襲&#xff01;這是一份專為開發者與電商從業者打造的超詳細指南。從項目基礎搭建&#xff0c;運用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用戶、商品、訂單等核心模塊開發&#xff0c;再到性能優化、安全加固、多端適配&#xf…

《C++ Primer》學習筆記(二)

第二部分&#xff1a;C標準庫 1.為了支持不同種類的IO處理操作&#xff0c;標準庫定義了以下類型的IO&#xff0c;分別定義在三個獨立的文件中&#xff1a;iostream文件中定義了用于讀寫流的基本類型&#xff1b;fstream文件中定義了讀寫命名文件的類型&#xff1b;sstream文件…

MATLAB風光柴儲微網粒子群算法

本程序實現了風光柴儲微網中的粒子群優化&#xff08;PSO&#xff09;算法&#xff0c;用于優化微網的能源調度問題。具體來說&#xff0c;程序考慮了光伏發電、風力發電、柴油機發電&#xff08;柴儲&#xff09;&#xff0c;并使用粒子群算法來優化這些能源的調度&#xff0c…

解決Windows版Redis無法遠程連接的問題

&#x1f31f; 解決Windows版Redis無法遠程連接的問題 在Windows系統下使用Redis時&#xff0c;很多用戶會遇到無法遠程連接的問題。尤其是在配置了Redis并嘗試通過工具如RedisDesktopManager連接時&#xff0c;可能會報錯“Cannot connect to ‘redisconnection’”。今天&am…

解決 HTTP 請求中的編碼問題:從亂碼到正確傳輸

文章目錄 解決 HTTP 請求中的編碼問題&#xff1a;從亂碼到正確傳輸1. **問題背景**2. **亂碼問題的原因**2.1 **客戶端編碼問題**2.2 **請求頭缺失**2.3 **服務器編碼問題** 3. **解決方案**3.1 **明確指定請求體編碼**3.2 **確保請求頭正確**3.3 **動態獲取響應編碼** 4. **調…

VS Code 配置優化指南

目錄 一、安裝與基礎設置1. 安裝 VS Code2. 中文語言包 二、插件推薦三、常見配置項與優化1. 用戶 / 工作區設置2. 全局配置 / Settings Sync3. 常用設置示例 四、性能優化五、調試與終端配置1. 調試配置2. 內置終端配置 六、快捷鍵配置七、美觀與主題八、總結 VS Code&#xf…

基于NXP+FPGA永磁同步電機牽引控制單元(單板結構/機箱結構)

永磁同步電機牽引控制單元&#xff08;單板結構/機箱結構&#xff09; 永磁同步電機牽引控制單元&#xff08;TCU-PMSM&#xff09;用于牽引逆變器-永磁同步電機構成的牽引電傳動系統&#xff0c;采用軸控方式。執行高性能永磁同步電機復矢量控制策略&#xff0c;具有響應迅速…

/etc/sysconfig/jenkins 沒有這個文件

在 CentOS 或其他基于 Red Hat 的 Linux 系統中&#xff0c;/etc/sysconfig/jenkins 文件通常用來存儲 Jenkins 的配置參數&#xff0c;例如 JENKINS_HOME 的路徑。但是&#xff0c;如果你發現沒有這個文件&#xff0c;你可以通過以下幾種方式來解決或確認&#xff1a; 檢查 J…

conda 安裝軟件報錯 Found conflicts! Looking for incompatible packages.

問題描述&#xff1a; 利用 conda 安裝某包 conda install -c "nvidia/label/cuda-11.8.0" cuda-nvcc時發現報錯&#xff1a; Collecting package metadata (current_repodata.json): done Solving environment: failed with initial frozen solve. Retrying with…

MySQL 衍生表(Derived Tables)

在SQL的查詢語句select …. from …中&#xff0c;跟在from子句后面的通常是一張擁有定義的實體表&#xff0c;而有的時候我們會用子查詢來扮演實體表的角色&#xff0c;這個在from子句中的子查詢會返回一個結果集&#xff0c;這個結果集可以像普通的實體表一樣查詢、連接&…

STM32配套程序接線圖

1 工程模板 2 LED閃爍 3LED流水燈 4蜂鳴器 5按鍵控制LED 6光敏傳感器控制蜂鳴器 7OLED顯示屏 8對射式紅外傳感器計次 9旋轉編碼器計次 10 定時器定時中斷 11定時器外部時鐘 12PWM驅動LED呼吸燈 13 PWM驅動舵機 14 PWM驅動直流電機 15輸入捕獲模式測頻率 16PWMI模式測頻率占空…

鴻蒙初級考試備忘

Module類型 Module按照使用場景可以分為兩種類型&#xff1a; Ability類型的Module&#xff1a; 用于實現應用的功能和特性。每一個Ability類型的Module編譯后&#xff0c;會生成一個以.hap為后綴的文件&#xff0c;我們稱其為HAP&#xff08;Harmony Ability Package&#x…

語音識別踩坑記錄

本來想在原來的語音識別的基礎上增加本地擴展本地詞典&#xff0c; 采用的語音識別是Vosk識別器&#xff0c;模型是 vosk-model-small-cn-0.22 // 初始化Vosk識別器 if (recognizer null) {using (Model model new Model(modelPath)){string grammar "{""…

SpringCloud 學習筆記1(Spring概述、工程搭建、注冊中心、負載均衡、 SpringCloud LoadBalancer)

文章目錄 SpringCloudSpringCloud 概述集群和分布式集群和分布式的區別和聯系 微服務什么是微服務&#xff1f;分布式架構和微服務架構的區別微服務的優缺點&#xff1f;拆分微服務原則 什么是 SpringCloud &#xff1f;核心功能與組件 工程搭建父項目的 pom 文件 注冊中心Rest…

計算機網絡-網絡規劃與設計

基本流程 需求分析—》通信規范分析—》邏輯網絡設計—》物理網絡設計—》實施階段 需求分析&#xff1a; 確定需求&#xff0c;包括&#xff1a;業務需求、用戶需求、應用需求、計算機平臺需求、網絡通信需求等。 產物&#xff1a;需求規范 通信規范分析&#xff1a; 現有…

《AI浪潮中的璀璨新星:Meta Llama、Ollama與DeepSeek的深度剖析》:此文為AI自動生成

《AI浪潮中的璀璨新星&#xff1a;Meta Llama、Ollama與DeepSeek的深度剖析》&#xff1a;此文為AI自動生成 引言&#xff1a;AI 大模型的群雄逐鹿時代 在科技飛速發展的當下&#xff0c;AI 大模型領域已成為全球矚目的焦點&#xff0c;競爭激烈程度堪稱白熱化。從 OpenAI 推出…

基礎知識《HTTP字段與狀態碼詳細說明》

HTTP 協議字段與狀態碼完整指南 一、HTTP 字段&#xff08;請求頭與響應頭&#xff09; HTTP 頭字段用于傳遞客戶端和服務器之間的元數據&#xff0c;分為 請求頭&#xff08;Request Headers&#xff09; 和 響應頭&#xff08;Response Headers&#xff09;。 1. 常見請求頭…