Redis应用场景很多,现在介绍一下它的几大特性之一   发布订阅(pub/sub)

特性介绍:

  什么是redis的发布订阅(pub/sub)?   Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。熟悉设计模式的朋友应该了解这与23种设计模式中的观察者模式极为相似。 

     同样,Redis的pub/sub是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,  Redis作为一个pub/sub的server, 在订阅者和发布者之间起到了消息路由的功能。

  上面的都是概念,不知道没关系,其实我也看不懂。

简单来讲,这里面还有个channel的概念,这里就是频道的意思,比如你订阅了银行的频道,当你的资金发生变动时,银行就会通过它的频道给你发送信息,在这里,你是属于被动接收的,而不是向银行索要信息,这个例子中,你就是sub(订阅者),而银行就是pub(发布者)。

 

代码:

先引入依赖

  1. <dependency>  
  2.     <groupId>redis.clients</groupId>  
  3.     <artifactId>jedis</artifactId>  
  4.     <version>2.9.0</version>  
  5. </dependency>  

新建一个发布者

  1. public class Publisher extends Thread{  
  2.     private final JedisPool jedisPool;  
  3.   
     
  4.     public Publisher(JedisPool jedisPool) {  
  5.         this.jedisPool = jedisPool;  
  6.     }  
  7.   
     
  8.     @Override  
  9.     public void run() {  
  10.         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
  11.         Jedis jedis = jedisPool.getResource();   //连接池中取出一个连接  
  12.         while (true) {  
  13.             String line = null;  
  14.             try {  
  15.                 line = reader.readLine();  
  16.                 if (!"quit".equals(line)) {  
  17.                     jedis.publish("mychannel", line);   //从 mychannel 的频道上推送消息  
  18.                 } else {  
  19.                     break;  
  20.                 }  
  21.             } catch (IOException e) {  
  22.                 e.printStackTrace();  
  23.             }  
  24.         }  
  25.     }  
  26. }  

新建一个订阅者

  1. public class Subscriber extends JedisPubSub {  
  2.   
     
  3.     public Subscriber(){}  
  4.     @Override  
  5.     public void onMessage(String channel, String message) {       //收到消息会调用  
  6.         System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));  
  7.     }  
  8.     @Override  
  9.     public void onSubscribe(String channel, int subscribedChannels) {    //订阅了频道会调用  
  10.         System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",  
  11.                 channel, subscribedChannels));  
  12.     }  
  13.     @Override  
  14.     public void onUnsubscribe(String channel, int subscribedChannels) {   //取消订阅 会调用  
  15.         System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",  
  16.                 channel, subscribedChannels));  
  17.   
     
  18.     }  
  19. }

订阅频道

  1. public class SubThread extends Thread {  
  2.     private final JedisPool jedisPool;  
  3.     private final Subscriber subscriber = new Subscriber();  
  4.   
     
  5.     private final String channel = "mychannel";  
  6.   
     
  7.     public SubThread(JedisPool jedisPool) {  
  8.         super("SubThread");  
  9.         this.jedisPool = jedisPool;  
  10.     }  
  11.   
     
  12.     @Override  
  13.     public void run() {  
  14.         System.out.println(String.format("subscribe redis, channel %s, thread will be blocked", channel));  
  15.         Jedis jedis = null;  
  16.         try {  
  17.             jedis = jedisPool.getResource();   //取出一个连接  
  18.             jedis.subscribe(subscriber, channel);    //通过subscribe 的api去订阅,入参是订阅者和频道名  
  19.         } catch (Exception e) {  
  20.             System.out.println(String.format("subsrcibe channel error, %s", e));  
  21.         } finally {  
  22.             if (jedis != null) {  
  23.                 jedis.close();  
  24.             }  
  25.         }  
  26.     }  
  27. }  
  28.  
     

测试下

  1. public class PubSubDemo {  
  2.     public static void main( String[] args )  
  3.     {  
  4.         // 连接redis服务端  
  5.         JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "172.31.12.18", 7379);  
  6.   
     
  7.         System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", "127.0.0.1", 7379));  
  8.   
     
  9.         SubThread subThread = new SubThread(jedisPool);  //订阅者  
  10.         subThread.start();  
  11.   
     
  12.         Publisher publisher = new Publisher(jedisPool);    //发布者  
  13.         publisher.start();  
  14.     }  
  15. }  

 

打印信息

 

 

 

Redis订阅广播实现多级缓存的更多相关文章

  1. redis订阅发布消息操作本地缓存

    Redis 本地缓存+远程缓存方案 使用纯java的ehcache作为本地缓存 Reids 作为远程分布式缓存 解决redis缓存压力过大,提高缓存速度,以及缓存性能. Redis和ehcache缓存 ...

  2. Redis 多级缓存架构和数据库与缓存双写不一致问题

    采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...

  3. Redis: 缓存过期、缓存雪崩、缓存穿透、缓存击穿(热点)、缓存并发(热点)、多级缓存、布隆过滤器

    Redis: 缓存过期.缓存雪崩.缓存穿透.缓存击穿(热点).缓存并发(热点).多级缓存.布隆过滤器 2019年08月18日 16:34:24 hanchao5272 阅读数 1026更多 分类专栏: ...

  4. 【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)

    一.缓存 当系统的并发量上来了,如果我们频繁地去访问数据库,那么会使数据库的压力不断增大,在高峰时甚至可以出现数据库崩溃的现象.所以一般我们会使用缓存来解决这个数据库并发访问问题,用户访问进来,会先从 ...

  5. 带你100% 地了解 Redis 6.0 的客户端缓存

    近日 Redis 6.0.0 GA 版本发布,这是 Redis 历史上最大的一次版本更新,包括了客户端缓存 (Client side caching).ACL.Threaded I/O 和 Redis ...

  6. 有赞透明多级缓存解决方案(TMC)设计思路

    引子 TMC 是什么 TMC,即"透明多级缓存(Transparent Multilevel Cache)",是有赞 PaaS 团队给公司内应用提供的整体缓存解决方案. TMC 在 ...

  7. Redis整合Spring结合使用缓存实例(三)

    一.Redis介绍 什么是Redis? redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set( ...

  8. Redis整合Spring结合使用缓存实例

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文介绍了如何在Spring中配置redis,并通过Spring中AOP的思想,将缓存的 ...

  9. Redis整合Spring结合使用缓存实例(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文介绍了如何在Spring中配置redis,并通过Spring中AOP的思想,将缓存的 ...

随机推荐

  1. 使用.Net Core 2.2创建windows服务

    使用.Net Core 2.2创建windows服务 我的环境 win 10 home Visual Studio 2019 v16.1.3 安装有.net core 2.2 创建项目 编辑项目文件 ...

  2. net core体系-Xamarin-2概要(lignshi)

    通过本套课程的学习,各位学员能够对Xamarin有一个比较清楚的认识,掌握Xamarin常用功能的使用方法,能够比较熟练的使用Xamarin进行App(移动应用)的开发,能够比较轻松.快速地投入项目当 ...

  3. 4. Java入门程序

    以eclipse为例,建立一个简单的Java程序. 首先启动eclipse,进入到如下主页面: 新建一个项目,选择“File-New-Java Project”: 弹出了一个如下页面,假设命名为Tes ...

  4. springboot-异步、发送邮件(二)

    @Test //发送复杂邮件 void contextLoads2() throws MessagingException { MimeMessage mimeMessage = mailSender ...

  5. scrapy增量爬取

    ​开始接触爬虫的时候还是初学Python的那会,用的还是request.bs4.pandas,再后面接触scrapy做个一两个爬虫,觉得还是框架好,可惜都没有记录都忘记了,现在做推荐系统需要爬取一定的 ...

  6. vue统一注册组件

    文件夹下面组件数量较多,如果每一个组件先import然后在 components,虽然灭有问题,但是会导致代码量大,而且不直观 解决办法: 将图元组件进行统一注册 新建一个pixels文件,文件里面的 ...

  7. android默认获取敏感权限

    1.通过系统签名获取权限 定制系统中,可以通过源码的签名文件对应用进行签名,在应用的AndroidManifest.xml中配置好参数,如图 <manifest xmlns:android=&q ...

  8. 《Linux就该这么学》day4-6

    继续学习打卡,这几天有事所以看视频补上了这几天的学习进度. day4:主要重点 tar打包和解压命令 tar -zxvf  xxx.tar.gz 解压xxx.tar.gz   (将xxx.tar.gz ...

  9. 异步处理的框架Sanic的使用方法和小技巧

    Sanic是异步处理的框架,运用Sanic可以开发快速异步响应的web程序.想必大家看到这个都会比较期待和兴奋. 那么如何使用Sanic来实现快速响应呢?我们先来看一看Sanic的基本介绍. Sani ...

  10. python面向对象:组合、封装、property装饰器、多态

    一.组合二.封装三.property装饰器四.多态 一.组合 ''' 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 3. ...