最通俗易懂的Redis发布订阅及代码实战
发布订阅简介
除了使用List实现简单的消息队列功能以外,Redis还提供了发布订阅的消息机制。在这种机制下,消息发布者向指定频道(channel)发布消息,消息订阅者可以收到指定频道的消息,同一个频道可以有多个消息订阅者,如下图:
Redis也提供了一些命令支持这个机制,接下来我们详细介绍一下这些命令。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
发布订阅相关命令
在Redis中,发布订阅相关命令有:
- 发布消息
- 订阅频道
- 取消订阅
- 按照模式订阅
- 按照模式取消订阅
- 查询订阅信息
发布消息
发布消息的命令是publish
,语法是:
publish 频道名称 消息
比如,要向channel:one-more-study:demo频道发布一条消息“I am One More Study.”,命令如下:
> publish channel:one-more-study:demo "I am One More Study."
(integer) 0
返回的结果是订阅者的个数,上例中没有订阅者,所以返回结果为0。
订阅消息
订阅消息的命令是subscribe
,订阅者可以订阅一个或者多个频道,语法是:
subscribe 频道名称 [频道名称 ...]
比如,订阅一个channel:one-more-study:demo频道,命令如下:
> subscribe channel:one-more-study:demo
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:one-more-study:demo"
3) (integer) 1
返回结果中有3条,分别表示:返回值的类型(订阅成功)、订阅的频道名称、目前已订阅的频道数量。当订阅者接受到消息时,就会显示:
1) "message"
2) "channel:one-more-study:demo"
3) "I am One More Study."
同样也是3条结果,分别表示:返回值的类型(信息)、消息来源的频道名称、消息内容。
新开启的订阅者,是无法收到该频道之前的历史消息的,因为Redis没有对发布的消息做持久化。
取消订阅
取消订阅的命令是unsubscribe
,可以取消一个或者多个频道的订阅,语法是:
unsubscribe [频道名称 [频道名称 ...]]
比如,取消订阅channel:one-more-study:demo频道,命令如下:
> unsubscribe channel:one-more-study:demo
1) "unsubscribe"
2) "channel:one-more-study:demo"
3) (integer) 0
返回结果中有3条,分别表示:返回值的类型(取消订阅成功)、取消订阅的频道名称、目前已订阅的频道数量。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
按模式订阅消息
按模式订阅消息的命令是psubscribe
,订阅一个或多个符合给定模式的频道,语法是:
psubscribe 模式 [模式 ...]
每个模式以 * 作为匹配符,比如 channel* 匹配所有以 channel 开头的频道,命令如下:
> psubscribe channel:*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "channel*"
3) (integer) 1
返回结果中有3条,分别表示:返回值的类型(按模式订阅成功)、订阅的模式、目前已订阅的模式数量。当订阅者接受到消息时,就会显示:
1) "pmessage"
2) "channel*"
3) "channel:one-more-study:demo"
4) "I am One More Study."
返回结果中有4条,分别表示:返回值的类型(信息)、消息匹配的模式、消息来源的频道名称、消息内容。
按模式取消订阅
按模式取消订阅的命令是punsubscribe
,可以取消一个或者多个模式的订阅,语法是:
punsubscribe [模式 [模式 ...]]
每个模式以 * 作为匹配符,比如 channel:* 匹配所有以 channel 开头的频道,命令如下:
1> punsubscribe channel:*
1) "punsubscribe"
2) "channel:*"
3) (integer) 0
返回结果中有3条,分别表示:返回值的类型(按模式取消订阅成功)、取消订阅的模式、目前已订阅的模式数量。
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
查询订阅信息
查看活跃频道
活跃频道指的是至少有一个订阅者的频道,语法是:
pubsub channels [模式]
比如:
> pubsub channels
1) "channel:one-more-study:test"
2) "channel:one-more-study:demo"
3) "channel:demo"
> pubsub channels *demo
1) "channel:one-more-study:demo"
2) "channel:demo"
> pubsub channels *one-more-study*
1) "channel:one-more-study:test"
2) "channel:one-more-study:demo"
查看频道订阅数
pubsub numsub [频道名称 ...]
比如:
> pubsub numsub channel:one-more-study:demo
1) "channel:one-more-study:demo"
2) (integer) 1
查看模式订阅数
> pubsub numpat
(integer) 1
代码实战
光说不练假把式,我们使用Java语言写一个简单的发布订阅示例。
Jedis集群示例
Jedis是Redis官方推荐的Java连接开发工具,我们使用Jedis写一个简单的集群示例。
package onemore.study;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
/**
* Jedis集群
*
* @author 万猫学社
*/
public enum Cluster {
INSTANCE;
//为了简单,把IP和端口直接写在这里,实际开发中写在配置文件会更好。
private final String hostAndPorts = "192.168.0.60:6379;192.168.0.61:6379;192.168.0.62:6379";
private JedisCluster jedisCluster;
Cluster() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大连接数
poolConfig.setMaxTotal(20);
//最大空闲数
poolConfig.setMaxIdle(10);
//最小空闲数
poolConfig.setMinIdle(2);
//从jedis连接池获取连接时,校验并返回可用的连接
poolConfig.setTestOnBorrow(true);
//把连接放回jedis连接池时,校验并返回可用的连接
poolConfig.setTestOnReturn(true);
Set<HostAndPort> nodes = new HashSet<>();
String[] hosts = hostAndPorts.split(";");
for (String hostport : hosts) {
String[] ipport = hostport.split(":");
String ip = ipport[0];
int port = Integer.parseInt(ipport[1]);
nodes.add(new HostAndPort(ip, port));
}
jedisCluster = new JedisCluster(nodes, 1000, poolConfig);
}
public JedisCluster getJedisCluster() {
return jedisCluster;
}
}
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
发布者示例
package onemore.study;
import redis.clients.jedis.JedisCluster;
/**
* 发布者
*
* @author 万猫学社
*/
public class Publisher implements Runnable {
private final String CHANNEL_NAME = "channel:one-more-study:demo";
private final String QUIT_COMMAND = "quit";
@Override
public void run() {
JedisCluster jedisCluster = Cluster.INSTANCE.getJedisCluster();
for (int i = 1; i <= 3; i++) {
String message = "第" + i + "消息";
System.out.println(Thread.currentThread().getName() + " 发布:" + message);
jedisCluster.publish(CHANNEL_NAME, message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------");
}
jedisCluster.publish(CHANNEL_NAME, QUIT_COMMAND);
}
}
订阅者示例
package onemore.study;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPubSub;
/**
* 订阅者
*
* @author 万猫学社
*/
public class Subscriber implements Runnable {
private final String CHANNEL_NAME = "channel:one-more-study:demo";
private final String QUIT_COMMAND = "quit";
private final JedisPubSub jedisPubSub = new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
System.out.println(Thread.currentThread().getName() + " 接收:" + message);
if (QUIT_COMMAND.equals(message)) {
unsubscribe(CHANNEL_NAME);
}
}
};
@Override
public void run() {
JedisCluster jedisCluster = Cluster.INSTANCE.getJedisCluster();
jedisCluster.subscribe(jedisPubSub, CHANNEL_NAME);
}
}
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
综合示例
package onemore.study;
public class App {
public static void main(String[] args) throws InterruptedException {
//创建3个订阅者
new Thread(new Subscriber()).start();
new Thread(new Subscriber()).start();
new Thread(new Subscriber()).start();
Thread.sleep(1000);
//创建发布者
new Thread(new Publisher()).start();
}
}
运行结果如下:
Thread-6 发布:第1消息
Thread-0 接收:第1消息
Thread-1 接收:第1消息
Thread-2 接收:第1消息
------------------
Thread-6 发布:第2消息
Thread-0 接收:第2消息
Thread-1 接收:第2消息
Thread-2 接收:第2消息
------------------
Thread-6 发布:第3消息
Thread-0 接收:第3消息
Thread-2 接收:第3消息
Thread-1 接收:第3消息
------------------
Thread-0 接收:quit
Thread-1 接收:quit
Thread-2 接收:quit
微信公众号:万猫学社
微信扫描二维码
获得更多Java技术干货

最通俗易懂的Redis发布订阅及代码实战的更多相关文章
- redis发布订阅Java代码实现
Redis除了可以用作缓存数据外,另一个重要用途是它实现了发布订阅(pub/sub)消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 为了实现redis的发布订阅机制,首先要打开re ...
- 我在生产项目里是如何使用Redis发布订阅的?(二)Java版代码实现(含源码)
上篇文章讲了在实际项目里的哪些业务场景用到Redis发布订阅,这篇文章就讲一下,在Java中如何实现的. 图解代码结构 发布订阅的理论以及使用场景大家都已经有了大致了解了,但是怎么用代码实现发布订阅呢 ...
- RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...
- Redis发布订阅机制
1. 什么是Redis Redis是一个开源的内存数据库,它以键值对的形式存储数据.由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,因此,Redis也 ...
- Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门
一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...
- 使用EventBus + Redis发布订阅模式提升业务执行性能
前言 最近一直奔波于面试,面了几家公司的研发.有让我受益颇多的面试经验,也有让我感觉浪费时间的面试经历~因为疫情原因,最近宅在家里也没事,就想着使用Redis配合事件总线去实现下具体的业务. 需求 一 ...
- Redis 发布订阅,小功能大用处,真没那么废材!
今天小黑哥来跟大家介绍一下 Redis 发布/订阅功能. 也许有的小伙伴对这个功能比较陌生,不太清楚这个功能是干什么的,没关系小黑哥先来举个例子. 假设我们有这么一个业务场景,在网站下单支付以后,需要 ...
- redis发布订阅客户端报错
转自简书[https://www.jianshu.com/p/a85ec38245da] 最近遇到一个问题,springBoot程序中有一个监听器,监听redis中发来的消息(其实是监听一个key的消 ...
- Python 操作 Redis 发布订阅
Python 操作 Redis 发布订阅 介绍 Redis可以通过多个客户机订阅相同的频道,一个服务机在相应频道进行发布,从而实现在客户机收听服务机发布相应信息,可以利用这个机制实现多个客户机之间的信 ...
随机推荐
- PTA-7-20 表达式转换(中缀转后缀,带括号,负数,小数转换)
本题考点:中缀表达式转后缀表达式. 难点: 带有小数的数字 数字可能带有正负号 题目描述: 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元运算符位于 ...
- ArcSDE数据库、文件地理数据库和个人地理数据库的区别
Geodatabase地理数据库分为: Personal Geodastabase个人地理数据库, File Geodatabase文件地理数据库, ArcSDE Geodatabase SDE地理数 ...
- 硬不硬你说了算!35 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
每日一句英语学习,每天进步一点点: 前言 不管面试 Java .C/C++.Python 等开发岗位, TCP 的知识点可以说是的必问的了. 任 TCP 虐我千百遍,我仍待 TCP 如初恋. 遥想小林 ...
- 不可被忽视的操作系统( FreeRTOS )【1】
把大多数人每个星期的双休过过成了奢侈的节假日放假,把每天23点后定义为自己的自由时间,应该如何去思考这个问题 ? 双休的两天里,不!是放假的两天里,终于有较长的时间好好的学习一下一直断断续续的Free ...
- Mac OS修改VSCode Go的默认缩进格式
一.在VSCode中编写Go代码时,缩进是使用tab缩进,主要是由于以下两个方面. 1. Go官方提供的代码格式化工具gofmt默认是使用tab缩进,并且为8个字符宽度. 2. 并且在VSCode中, ...
- 创建Windows10无人值守(自动应答文件)教程
一.准备工作 系统要求: Windows10 1809版本 工具下载: 镜像:Windows10,任何一个版本都可以,我使用的是1909版本 ed2k://|file|cn_windows_10_bu ...
- JavaScript简单使用
本文参考廖雪峰老师网站:https://www.liaoxuefeng.com/wiki/1022910821149312 JavaScript是一种运行在浏览器中的解释型的编程语言,在Web世界里, ...
- 《Three.js 入门指南》3.1.1 - 基本几何形状-立方体(CubeGeometry)
3.1 基本几何形状 立方体(CubeGeometry) 构造函数: THREE.CubeGeometry(width, height, depth, widthSegments, heightSeg ...
- 【JavaScript】js01
一,javascript 历史. netscape -> 浏览器. -> livescript 微软 -> jscript netscape -> ecma 组织 -> ...
- java文件中出现最多的前n个单词
将文件打开,之后每读入一次,最后按空格进行分割.存入到map里面之后进行相应的比较输出操作.并将相应的内容输出到文件里面. package com.keshangone; //将想要输出的数据写入新的 ...