1.概念
名稱及含義
channel 頻道:生產者和消費者直接操作的物件
publish 生產者:向channel發送訊息
subscribe 消費者:訂閱一個或多個channel
psubscribe 消費者:匹配訂閱一個或多個channel
punsubscribe 退訂:匹配退訂,無引數則退訂全部channel
unsubscribe 退訂:退訂指定的channel,無引數則退訂全部channel
pubsub 列出當前活動channel(至少有一個訂閱)
2.注意事項
1)生產者publish訊息時打開一個連接,publish后連接可以立即關閉
2)channel只接收publish發送的訊息,自身不存盤訊息,如果channel沒有被訂閱,則訊息丟棄
3)訂閱的消費者需要一直在線,阻塞獲取訊息,連接斷開表示立即退訂
3.redis可以實作發布訂閱和訊息佇列的功能,兩者的區別在于:
1)redis的訂閱者可以是多個,且可以同時處理發布上來的訊息,如果訂閱者不在線(服務沒有啟動)訊息將丟失,訊息沒有持久化,發布和訂閱是一塊執行的,缺少一個直接忽略這個訊息
2)訊息佇列只能有一個客戶端來處理,處理完之后訊息就被標記或洗掉,即使服務端沒有啟動訊息也不會丟失
3)兩者的使用場景要根據業務資料的準確度,敏感性決定,比如日志就可以用redis發布訂閱來實作,丟失一點也沒有關系
4.直接使用php-redis擴展提供的方法實作發布訂閱
1)消費者訂閱Subscribe.php
<?php
//設定php腳本執行時間
set_time_limit(0);
//設定socket連接超時時間
ini_set('default_socket_timeout', -1);
//宣告測驗頻道名稱
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
try {
$redis = new Redis();
//建立一個長鏈接
$redis->pconnect('ip', 6379);
//阻塞獲取訊息
$redis->subscribe(array($channelName, $channelName2), function ($redis, $chan, $msg) {
echo "channel:".$chan.",message:".$msg."\n";
});
} catch (Exception $e) {
echo $e->getMessage();
}
2)生產者發送訊息Publish.php
<?php
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
//向指定頻道發送訊息
try {
$redis = new Redis();
$redis->connect('192.168.75.132', 6379);
for ($i=0;$i<5;$i++) {
$data = https://www.cnblogs.com/WebLinuxStudy/p/array('key' => 'key'.$i, 'data' => 'testdata');
$ret = $redis->publish($channelName, json_encode($data));
print_r($ret);
}
} catch (Exception $e) {
echo $e->getMessage();
}
3)執行消費者訂閱,開始阻塞獲取訊息php Subscribe.php
4)執行生產者,開始發送訊息php Publish.php
php .\Publish.php
22222
#回傳執行結果:頻道的訂閱數量
查看消費者終端
php .\Subscribe.php
channel:testPubSub,message:{"key":"key0","data":"testdata"}
channel:testPubSub,message:{"key":"key1","data":"testdata"}
channel:testPubSub,message:{"key":"key2","data":"testdata"}
channel:testPubSub,message:{"key":"key3","data":"testdata"}
channel:testPubSub,message:{"key":"key4","data":"testdata"}
轉自:https://www.jmsite.cn/blog-586.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/6063.html
標籤:NoSQL
下一篇:Redis的三大問題
