认识
2025年01月07日
一、认识
Redis
发布订阅(Pub/Sub
) 是一种消息通信模式,允许不同的客户端(发布者和订阅者)进行解耦通信,广泛应用于消息推送、事件通知等场景。
Redis
发布订阅(Pub/Sub
)概念:
-
频道(
Channel
): 一个逻辑上的消息通道,客户端可以订阅该频道,接收从该频道发布的消息。 -
发布(
Publish
):将消息发送到指定频道的操作。 -
订阅(
Subscribe
): 客户端订阅一个或多个频道,接收相应频道的消息。
Redis
发布订阅(Pub/Sub
)工作:
-
Redis
服务器,Redis
作为中介,负责接收发布者发送的消息,并将这些消息转发给所有订阅该频道的客户端。 -
发布者(
Publisher
), 发布者将消息发送到一个特定的频道(Channel
)。消息本身并不直接发送到订阅者,而是通过Redis
进行传递。 -
订阅者(
Subscriber
), 订阅者可以订阅一个或多个频道。任何发布到这些频道的消息都会被Redis
推送到所有订阅了这些频道的客户端。
Redis
发布订阅(Pub/Sub
)特点:
-
无消息确认, 发布订阅是 火车头模式 的推送,没有确认机制。如果消息发送失败或订阅者未能及时处理,消息将丢失。
-
消息丢失, 如前所述,
Redis
的Pub/Sub
机制不持久化消息,因此如果订阅者在消息发布时未在线或未及时接收,消息将不会被保存。
二、语法
2.1 同线程
const Redis = require("ioredis");
const sub = new Redis();
const pub = new Redis();
sub.subscribe(/* ... */); // From now, `sub` enters the subscriber mode.
sub.on("message" /* ... */);
setInterval(() => {
// `pub` can be used to publish messages, or send other regular commands (e.g. `hgetall`)
// because it's not in the subscriber mode.
pub.publish(/* ... */);
}, 1000);
2.2 异线程
发布者(Publisher
)
const Redis = require("ioredis");
const redis = new Redis();
setInterval(() => {
const message = { foo: Math.random() };
// Publish to my-channel-1 or my-channel-2 randomly.
const channel = `my-channel-${1 + Math.round(Math.random())}`;
// Message can be either a string or a buffer
redis.publish(channel, JSON.stringify(message));
console.log("Published %s to %s", message, channel);
}, 1000);
订阅者(Subscriber
)
const Redis = require("ioredis");
const redis = new Redis();
redis.subscribe("my-channel-1", "my-channel-2", (err, count) => {
if (err) {
// Just like other commands, subscribe() can fail for some reasons,
// ex network issues.
console.error("Failed to subscribe: %s", err.message);
} else {
// `count` represents the number of channels this client are currently subscribed to.
console.log(
`Subscribed successfully! This client is currently subscribed to ${count} channels.`
);
}
});
redis.on("message", (channel, message) => {
console.log(`Received ${message} from ${channel}`);
});
// There's also an event called 'messageBuffer', which is the same as 'message' except
// it returns buffers instead of strings.
// It's useful when the messages are binary data.
redis.on("messageBuffer", (channel, message) => {
// Both `channel` and `message` are buffers.
console.log(channel, message);
});