Redis:20---常用功能之(發布與訂閱)

一、發布與訂閱概述

  • Redis提供了基于“發布/訂閱”模式的消息機制,此種模式下,消息發布者和訂閱者不進行直接通信,發布者客戶端向指定的頻道(channel)發布消息,訂閱該頻道的每個客戶端都可以收到該消息。

  • ?下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關系:

當有新消息通過 PUBLISH 命令發送給頻道 channel1 時, 這個消息就會被發送給訂閱它的三個客戶端:

  • Redis主要提供了發布消息、訂閱頻道、取消訂閱以及按照模式訂閱和取消訂閱等命令

二、發布消息(publish)

PUBLISH <channel> <message>
  • 當一個客戶端執行PUBLISH命令的時候,會將消息message發送給頻道channel

  • 例如:下面操作會向channel:sports頻道發布一條消息“Tim won the championship”,返回結果為訂閱者個數,因為此時沒有訂閱,所以返回結果為0

publish channel:sports "Tim won the championship"

二、訂閱消息(subscribe)

subscribe channel [channel...]
  • 訂閱者可以訂閱一個或多個頻道

  • 注意事項:

    • 客戶端在執行訂閱命令之后進入了訂閱狀態,只能接收subscribe、 psubscribe、unsubscribe、punsubscribe的四個命令

    • 新開啟的訂閱客戶端,無法收到該頻道之前的消息,因為Redis不會對發布的消息進行持久化

演示案例

  • 下面操作為當前客戶端訂閱了channel:sports頻道:

subscribe channel:sports

?

  • 此時右側另一個客戶端向channel:sports頻道發布一條消息,右側客戶端會收到這條消息

publish channel:sports "James lost the championship"

  • 開發提示:和很多專業的消息隊列系統(例如Kafka、RocketMQ)相比,Redis的發布訂閱略顯粗糙,例如無法實現消息堆積和回溯。但勝在足夠簡單,如果當前場景可以容忍的這些缺點,也不失為一個不錯的選擇

三、取消訂閱(unsubscribe)

unsubscribe [channel [channel ...]]
  • 客戶端可以通過unsubscribe命令取消對指定頻道的訂閱,取消成功后, 不會再收到該頻道的發布消息

  • 取消訂閱只對本個客戶端有效,不會對其他客戶端造成影響

  • 例如:

?

四、模式訂閱/取消模式訂閱(psubscribe、punsubscribe)

psubscribe pattern [pattern...]
punsubscribe [pattern [pattern ...]]
  • psubscribe和punsubscribe是支持glob風格的訂閱/取消訂閱,稱之為“模式訂閱”

例如:

  • 下面左側客戶端訂閱以it開頭的所有頻道

psubscribe it*

?

  • 右側客戶端向itformation頻道發送一條消息,左側客戶端可以收到這條消息

五、查詢訂閱

①查詢活躍的頻道

pubsub channels [pattern]
  • 所謂活躍的頻道是指當前頻道至少有一個訂閱者,其中[pattern]是可以指定具體的模式

  • 例如,下面左側客戶端訂閱一個名為“it_redis”的頻道,右側使用pubsub查詢,結果會顯示出來

  • 當然,我們也可以具體指出查詢哪個頻道,如果頻道不存在會返回空

  • 當有模式訂閱時,也可以檢測出來

②查看頻道訂閱數

pubsub numsub [channel ...]
  • 該命令不僅可以檢測出是否有活躍的頻道,還能檢測出頻道的訂閱數

  • 例如,左側一個客戶端訂閱channel:sports頻道,右側客戶端查詢結果為1

③查看模式訂閱數

pubsub numpat
  • 該命令可以查詢出當前服務器中有多少個模式訂閱

  • 例如,當前所有客戶端中只有左側一個訂閱,并且不是模式訂閱,所以右側結果顯示為0

  • 現在我們在左側開啟模式訂閱,右側查詢結果顯示為1

六、發布-訂閱的使用場景

  • 聊天室、公告牌、服務之間利用消息解耦都可以使用發布訂閱模式

  • 下面以簡單的服務解耦進行說明。如下圖所示,圖中有兩套業務:

    • 上面為視頻管理系統,負責管理視頻信息

    • 下面為視頻服務面向客戶,用戶可以通過各種客戶端(手機、瀏覽器、接口)獲取到視頻信息

  • 假如視頻管理員在視頻管理系統中對視頻信息進行了變更,希望及時通知給視頻服務端,就可以采用發布訂閱的模式,發布視頻信息變化的消息到指定頻道,視頻服務訂閱這個頻道及時更新視頻信息,通過這種方式可以有效解決兩個業務的耦合性

  • 視頻服務訂閱video:changes頻道如下:

subscribe video:changes
  • 視頻管理系統發布消息到video:changes頻道如下:

publish video:changes "video1,video3,video5"
  • 當視頻服務收到消息,對視頻信息進行更新,如下所示:

for video in video1,video3,video5
update {video}

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

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

相關文章

Redis:19---常用功能之(HyperLogLog)

一、HyperLogLog概述HyperLogLog并不是一種新的數據結構&#xff08;實際類型為字符串類型&#xff09;&#xff0c;而是一種基數算法&#xff0c;通過HyperLogLog可以利用極小的內存空間完成獨立總數的統計&#xff0c;數據集可以是IP、Email、ID等HyperLogLog提供了3個命令&a…

計算時間差的Oracle函數

Oracle函數可以實現諸多的功能&#xff0c;下面就介紹使用Oracle函數計算時間差的實現方法&#xff0c;如果您對Oracle函數方面感興趣的話&#xff0c;不妨一看。 兩個Date類型字段&#xff1a;START_DATE&#xff0c;END_DATE&#xff0c;計算這兩個日期的時間差&#xff08;分…

leetcode181. 超過經理收入的員工(SQL)

Employee 表包含所有員工&#xff0c;他們的經理也屬于員工。每個員工都有一個 Id&#xff0c;此外還有一列對應員工的經理的 Id。 ------------------------------ | Id | Name | Salary | ManagerId | ------------------------------ | 1 | Joe | 70000 | 3 |…

UNIX(多線程):01---線程簡介及線程限制

一、線程的概念 典型的UNIX進程可以看成只有一個控制線程:一個進程在同一時刻只做一件事。有了多個控制線程后,在程序設計時可以把進程設計成在同一時刻能夠做不止一件事,每個線程處理各自獨立的任務二、線程的優點 通過為每種事件類型分配單獨的處理線程,可以簡化處理異步…

UNIX(多線程):13---condition_variable、wait、notify_one、notify_all

條件變量std::condition_variable、wait()、notify_one() 線程A: 等待一個條件滿足線程B: 專門往消息隊列中放入消息(數據),達到一定條件,通知處于等待中的線程A。std::condition_variable實際上是一個類,是一個和條件相關的一個類,說白了就是等待一個條件達成。這個類是…

leetcode176. 第二高的薪水(SQL)

編寫一個 SQL 查詢&#xff0c;獲取 Employee 表中第二高的薪水&#xff08;Salary&#xff09; 。 ------------ | Id | Salary | ------------ | 1 | 100 | | 2 | 200 | | 3 | 300 | ------------ 例如上述 Employee 表&#xff0c;SQL查詢應該返回 200 作為第二…

UNIX(多線程):17---異步任務提供者(Provider) 介紹

std::promise 類概述 Promise 對象可以保存某一類型 T 的值,該值可被 future 對象讀取(可能在另外一個線程中),因此 promise 也提供了一種線程同步的手段。在 promise 對象構造時可以和一個共享狀態(通常是std::future)相關聯,并可以在相關聯的共享狀態(std::future)上保…

leetcode180. 連續出現的數字(SQL)

編寫一個 SQL 查詢&#xff0c;查找所有至少連續出現三次的數字。 --------- | Id | Num | --------- | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | --------- 例如&#xff0c;給定上面的 Logs 表&#xff0c; 1 是唯一連續…

UNIX(多線程):18---異步任務提供者(Provider) 介紹(續)

本文主要介紹 std::packaged_task。 std::packaged_task 包裝一個可調用的對象,并且允許異步獲取該可調用對象產生的結果,從包裝可調用對象意義上來講,std::packaged_task 與 std::function 類似,只不過 std::packaged_task 將其包裝的可調用對象的執行結果傳遞給一個 std:…

leetcode182. 查找重復的電子郵箱(SQL)

編寫一個 SQL 查詢&#xff0c;查找 Person 表中所有重復的電子郵箱。 示例&#xff1a; ------------- | Id | Email | ------------- | 1 | ab.com | | 2 | cd.com | | 3 | ab.com | ------------- 根據以上輸入&#xff0c;你的查詢應返回以下結果&#xff1a; ----…

UNIX(多線程):19---Future 類型詳解

Future 類型詳解 本文主要介紹 std::future,std::shared_future 以及 std::future_error,另外還會介紹 <future> 頭文件中的 std::async,std::future_category 函數以及相關枚舉類型。 std::future 詳解 std::future 概述 前面已經多次提到過 std::future,那么 std::…

UNIX(多線程):20---生產者消費者實例

本文將綜合運用 C++11 中的新的基礎設施(主要是多線程、鎖、條件變量)來闡述一個經典問題——生產者消費者模型,并給出完整的解決方案。 生產者消費者問題是多線程并發中一個非常經典的問題,相信學過操作系統課程的同學都清楚這個問題的根源。本文將就四種情況分析并介紹生產…

leetcode183. 從不訂購的客戶(SQL)

某網站包含兩個表&#xff0c;Customers 表和 Orders 表。編寫一個 SQL 查詢&#xff0c;找出所有從不訂購任何東西的客戶。 Customers 表&#xff1a; ----------- | Id | Name | ----------- | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | ----------- Or…

UNIX(多線程):21---線程池實現原理

線程池簡介: 線程過多會帶來調度開銷,進而影響緩存局部性和整體性能。 而線程池維護著多個線程,等待著監督管理者分配可并發執行的任務。這避免了在處理短時間任務時創建與銷毀線程的代價。線程池不僅能夠保證內核的充分利用,還能防止過分調度。可用線程數量應該取決于可用…

leetcode197. 上升的溫度(SQL)

給定一個 Weather 表&#xff0c;編寫一個 SQL 查詢&#xff0c;來查找與之前&#xff08;昨天的&#xff09;日期相比溫度更高的所有日期的 Id。 --------------------------------------------- | Id(INT) | RecordDate(DATE) | Temperature(INT) | -----------------------…

UNIX(多線程):22---幾種常見的線程池

常見線程池 1、newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。 從構造方法來看,它可以單獨執行,也可以與周期線程池結合用。其任務隊列是LinkedBlockingQueue,這是個無界的阻塞…

js正則表達式限制文本框只能輸入數字,小數點,英文字母

1.文本框只能輸入數字代碼(小數點也不能輸入)<input οnkeyup"this.valuethis.value.replace(/\D/g,)" onafterpaste"this.valuethis.value.replace(/\D/g,)"> 2.只能輸入數字,能輸小數點. <input οnkeyup"if(isNaN(value))execCommand(und…

UNIX(多線程):23---線程池注意事項和常見問題

使用線程池的注意事項 死鎖任何多線程程序都有死鎖的風險,最簡單的情形是兩個線程AB,A持有鎖1,請求鎖2,B持有鎖2,請求鎖1。(這種情況在mysql的排他鎖也會出現,不會數據庫會直接報錯提示)。線程池中還有另一種死鎖:假設線程池中的所有工作線程都在執行各自任務時被阻塞…

leetcode 178. 分數排名(SQL)

編寫一個 SQL 查詢來實現分數排名。如果兩個分數相同&#xff0c;則兩個分數排名&#xff08;Rank&#xff09;相同。請注意&#xff0c;平分后的下一個名次應該是下一個連續的整數值。換句話說&#xff0c;名次之間不應該有“間隔”。 ----------- | Id | Score | ----------…

UNIX(多線程):24---哪些STL容器是線程安全的

在日常C++開發,少不了和STL,多線程打交道,那么在多線程下,哪些容器時線程安全的,那些不是? 好,這里就舉一個簡單的例子,我們先看看vector容器,相信你能看出一些問題: #include <iostream> #include <string> #include <algorithm> #inclu…