Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis客户端可以订阅任意数量的频道,下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
一个Redis client发布消息,其他多个redis client订阅消息,发布的消息“即发即失”,Redis不会持久保存发布的消息,消息订阅者也将只能得到订阅之后的消息,通道中此前的消息将无从获得。
消息发布者,无需独占链接,你可以在publish消息的同时,使用同一个redis-client链接进行其他操作。
消息订阅者,需要独占链接,即进行subscribe期间,redis-client无法穿插其他操作,此时client以阻塞的方式等待“publish端”的消息;因此这里subscribe端需要使用单独的链接,甚至需要在额外的线程中使用。
TCP默认连接时间固定,如果在这时间内sub端没有接收到pub端消息,或pub端没有消息产生,sub端的连接都会被强制回收。
# PHP实践
发布者:
<?php
// Redis发布订阅-发布者
require '../common.php';
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$i = 0;
while($i < 1000) {
print_log('send msg: '.'msg ' .$i);
$redis->publish('msg','msg ' .$i);
$i++;
sleep(1);
}
$redis->close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
订阅者:
<?php
// Redis发布订阅-订阅者
require '../common.php';
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->subscribe(['msg'], 'callback');
function callback($instance,$channelName,$message)
{
print_log('收到频道[ '.$channelName.' ]的消息:'.$message);
}
## 输出
21:53:05 收到频道[ msg ]的消息:msg 248
21:53:06 收到频道[ msg ]的消息:msg 249
21:53:07 收到频道[ msg ]的消息:msg 250
21:53:08 收到频道[ msg ]的消息:msg 251
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 应用场景
Redis利用发布订阅可以作为简单的消息队列来用,但是和专业的MQ中间件(RabbitMQ\Kafka)比较的话,没有持久化(可以用list替代)和ACK确认机制,适合于消息投递率要求不高的场景,例如:
- 短信发送、日志发送等功能解耦场景;
- 构建实时消息系统,比如普通的即时聊天,群聊等功能;
# 参考文档
上次更新: 2022/12/01, 11:09:34