1.概念名稱及含義channel 頻道:生產者和消費者直接操作的對象publish 生產者:向channel發送消息subscribe 消費者:訂閱一個或多個channelpsubscribe 消費者:匹配訂閱一個或多個channelpunsubscribe 退訂:匹配退訂,無參數則退訂全部chan ...
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 = 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