Redis(110)Redis的发布订阅机制如何使用?

Redis 的发布/订阅(Pub/Sub)机制允许消息的发布者和订阅者之间进行松耦合的消息传递。发布者将消息发布到特定的频道,而订阅者可以订阅该频道以接收消息。这种机制非常适合用于实时通知、消息广播等场景。

Redis 发布/订阅机制的基本使用

以下是 Redis 发布/订阅机制的详细使用方法和示例代码。

1. 启动 Redis 服务

确保 Redis 服务器正在运行。你可以通过命令行启动 Redis:

bash 复制代码
redis-server

2. 使用 Redis 客户端发布消息

可以使用 Redis 提供的客户端(如 Jedis)来发布和订阅消息。

发布者代码示例

java 复制代码
import redis.clients.jedis.Jedis;

public class RedisPublisher {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost")) {
            // 发布消息到频道 "my_channel"
            jedis.publish("my_channel", "Hello, Redis!");
            jedis.publish("my_channel", "Another message.");
        }
    }
}

订阅者代码示例

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisSubscriber {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost")) {
            // 创建订阅者
            JedisPubSub jedisPubSub = new JedisPubSub() {
                @Override
                public void onMessage(String channel, String message) {
                    System.out.println("Received message: " + message + " from channel: " + channel);
                }
            };

            // 订阅频道 "my_channel"
            jedis.subscribe(jedisPubSub, "my_channel");
        }
    }
}

3. 运行发布者和订阅者

  • 首先运行订阅者代码,订阅者将会等待接收来自 my_channel 频道的消息。
  • 然后运行发布者代码,发布者将消息发布到 my_channel 频道。订阅者将接收到并打印这些消息。

4. 详细示例:多个发布者和多个订阅者

发布者示例

java 复制代码
import redis.clients.jedis.Jedis;

public class RedisPublisher {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost")) {
            for (int i = 0; i < 5; i++) {
                String message = "Message " + i;
                System.out.println("Publishing message: " + message);
                jedis.publish("news_channel", message);
                try {
                    Thread.sleep(1000); // 等待1秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

订阅者示例

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisSubscriber {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost")) {
            // 创建订阅者
            JedisPubSub jedisPubSub = new JedisPubSub() {
                @Override
                public void onMessage(String channel, String message) {
                    System.out.println("Received message: " + message + " from channel: " + channel);
                }

                @Override
                public void onSubscribe(String channel, int subscribedChannels) {
                    System.out.println("Subscribed to channel: " + channel);
                }

                @Override
                public void onUnsubscribe(String channel, int subscribedChannels) {
                    System.out.println("Unsubscribed from channel: " + channel);
                }
            };

            // 订阅频道 "news_channel"
            jedis.subscribe(jedisPubSub, "news_channel");
        }
    }
}

5. 使用模式匹配订阅

除了订阅特定的频道外,Redis 还支持模式匹配订阅。模式订阅者可以订阅符合特定模式的所有频道。

模式订阅示例

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisPatternSubscriber {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost")) {
            // 创建模式订阅者
            JedisPubSub jedisPubSub = new JedisPubSub() {
                @Override
                public void onPMessage(String pattern, String channel, String message) {
                    System.out.println("Received message: " + message + " from channel: " + channel + " matching pattern: " + pattern);
                }

                @Override
                public void onPSubscribe(String pattern, int subscribedChannels) {
                    System.out.println("Subscribed to pattern: " + pattern);
                }

                @Override
                public void onPUnsubscribe(String pattern, int subscribedChannels) {
                    System.out.println("Unsubscribed from pattern: " + pattern);
                }
            };

            // 订阅匹配 "news.*" 模式的所有频道
            jedis.psubscribe(jedisPubSub, "news.*");
        }
    }
}

6. 发布订阅注意事项

  1. 消息丢失:Redis Pub/Sub 机制不保证消息的持久化。如果没有订阅者在线,消息将被丢弃。
  2. 消息顺序:消息按照发布的顺序被订阅者接收,但如果有多个订阅者,顺序不保证在所有订阅者之间一致。
  3. 性能:对于高流量或需要消息持久化的场景,可以考虑使用 Redis Streams 或其他消息队列系统(如 Kafka、RabbitMQ)。

7. 高级示例:多线程环境下的发布订阅

多线程发布者

java 复制代码
import redis.clients.jedis.Jedis;

public class MultiThreadRedisPublisher implements Runnable {
    private String channel;
    private String message;

    public MultiThreadRedisPublisher(String channel, String message) {
        this.channel = channel;
        this.message = message;
    }

    @Override
    public void run() {
        try (Jedis jedis = new Jedis("localhost")) {
            jedis.publish(channel, message);
            System.out.println("Published message: " + message + " to channel: " + channel);
        }
    }

    public static void main(String[] args) {
        Thread publisher1 = new Thread(new MultiThreadRedisPublisher("channel1", "Hello from publisher 1"));
        Thread publisher2 = new Thread(new MultiThreadRedisPublisher("channel2", "Hello from publisher 2"));

        publisher1.start();
        publisher2.start();
    }
}

多线程订阅者

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class MultiThreadRedisSubscriber implements Runnable {
    private String channel;

    public MultiThreadRedisSubscriber(String channel) {
        this.channel = channel;
    }

    @Override
    public void run() {
        try (Jedis jedis = new Jedis("localhost")) {
            JedisPubSub jedisPubSub = new JedisPubSub() {
                @Override
                public void onMessage(String channel, String message) {
                    System.out.println("Received message: " + message + " from channel: " + channel);
                }
            };

            jedis.subscribe(jedisPubSub, channel);
        }
    }

    public static void main(String[] args) {
        Thread subscriber1 = new Thread(new MultiThreadRedisSubscriber("channel1"));
        Thread subscriber2 = new Thread(new MultiThreadRedisSubscriber("channel2"));

        subscriber1.start();
        subscriber2.start();
    }
}

通过这些示例代码,展示了如何使用 Redis 的发布/订阅机制,包括基本的发布和订阅、模式匹配订阅以及多线程环境下的发布和订阅。Redis 的发布/订阅机制非常强大,可以用于各种实时消息传递的场景。

相关推荐
李梨同学丶11 分钟前
0201好虫子周刊
后端
思想在飞肢体在追20 分钟前
Springboot项目配置Nacos
java·spring boot·后端·nacos
Loo国昌3 小时前
【垂类模型数据工程】第四阶段:高性能 Embedding 实战:从双编码器架构到 InfoNCE 损失函数详解
人工智能·后端·深度学习·自然语言处理·架构·transformer·embedding
ONE_PUNCH_Ge4 小时前
Go 语言泛型
开发语言·后端·golang
良许Linux4 小时前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强4 小时前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设4 小时前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统
学IT的周星星4 小时前
Spring Boot Web 开发实战:第二天,从零搭个“会卖萌”的小项目
spring boot·后端·tomcat
郑州光合科技余经理4 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
Remember_9935 小时前
Spring 事务深度解析:实现方式、隔离级别与传播机制全攻略
java·开发语言·数据库·后端·spring·leetcode·oracle