发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。redis作为一个pub/sub server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个 channel,也可以向多个channel发送消息。

下面做个实验。这里使用两个不同的client一个是redis自带的redis-cli另一个是用java版客户端jedis写的。java代码如下:

package com.jd.redis.client;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPubSub;

publicclass TestPubSubextends JedisPubSub{

@Override

publicvoid onMessage(String channel, String message) {

System.out.println("onMessage: channel["+channel+"], message["+message+"]");

}

@Override

publicvoid onPMessage(String pattern, String channel, String message) {

System.out.println("onPMessage: channel["+channel+"], message["+message+"]");

}

@Override

publicvoid onSubscribe(String channel,int subscribedChannels) {

System.out.println("onSubscribe: channel["+channel+"],"+

"subscribedChannels["+subscribedChannels+"]");

}

@Override

publicvoid onUnsubscribe(String channel,int subscribedChannels) {

System.out.println("onUnsubscribe: channel["+channel+"], "+

"subscribedChannels["+subscribedChannels+"]");

}

@Override

publicvoid onPUnsubscribe(String pattern,int subscribedChannels) {

System.out.println("onPUnsubscribe: pattern["+pattern+"],"+

"subscribedChannels["+subscribedChannels+"]");

}

@Override

publicvoid onPSubscribe(String pattern,int subscribedChannels) {

System.out.println("onPSubscribe: pattern["+pattern+"], "+

"subscribedChannels["+subscribedChannels+"]");

}

publicstaticvoid main(String[] args) {

Jedis jr = null;

try {

jr = new Jedis("192.168.157.128", 6379, 0);//redis服务地址和端口号

TestPubSub sp = new TestPubSub();

sp.proceed(jr.getClient(),"news.share", "news.blog");

//sp.proceedWithPatterns(jr.getClient(), "news.*");

} catch (Exception e) {

e.printStackTrace();

}

finally{

if(jr!=null){

jr.disconnect();

}

}

}

}

代码就是用TestPubSub对象来订阅,对象中的那此onXXX方法监听到相应事件
1 首先运行此java程序;

onSubscribe: channel[news.share], subscribedChannels[1]

onSubscribe: channel[news.blog], subscribedChannels[2]

2 启动redis-cli

redis 127.0.0.1:6379> psubscribe news.*

Reading messages... (press Ctrl-C to quit)

1) "psubscribe"

2) "news.*"

3) (integer) 1

3 再启动一个redis-cli用来发布两条消息:

redis 127.0.0.1:6379> publish news.share "share a link http://www.google.com"

(integer) 2

redis 127.0.0.1:6379> publish news.blog "I post a blog"

(integer) 2

4.查看两个订阅client的输出 此时java client打印如下内容:

onMessage: channel[news.share], message[share a link http://www.google.com]

onMessage: channel[news.blog], message[I post a blog]

另一个redis-cli输出如下:

1) "pmessage"

2) "news.*"

3) "news.share"

4) "share a link http://www.google.com"

1) "pmessage"

2) "news.*"

3) "news.blog"

4) "I post a blog"

redis client使用psubscribe订阅了一个使用通配符的通道(*表示任意字符串),此订阅会收到所有与news.*匹配的通道消息。redis-  cli打印到控制台的订阅成功消息表示使用psubscribe命令订阅news.*成功后,连接订阅通道总数为1。
当我们在一个client使用publish向news.share和news.blog通道发出两个消息后。redis返回的(integer) 2表示有两个连接收到了此消息。
       看完一个小例子后应该对pub/sub功能有了一个感性的认识。需要注意的是当一个连接通过subscribe或者psubscribe订阅通道后就进入订阅模式。在这种模式除了再订阅额外的通道或者用unsubscribe或者punsubscribe命令退出订阅模式,就不能再发送其他命令。另外使用  psubscribe命令订阅多个通配符通道,如果一个消息匹配上了多个通道模式的话,会多次收到同一个消息。        redis的pub/sub还是有点太单薄(实现才用150行代码)。在安全,认证,可靠性这方便都没有太多支持

Redis学习笔记8--Redis发布/订阅的更多相关文章

  1. Redis学习笔记(1) Redis介绍及基础

    1. Redis的特性 (1) 存储结构 Redis(Remote Dictionary Server,远程字典服务器)是以字典结构存储数据,并允许其他应用通过TCP协议读写字典中的内容.Redis支 ...

  2. redis学习笔记之redis简介

    redis简介 Redis是一个开源的,高性能的,基于键值对的缓存与存储系统,通过设置各种键值数据类型来适应不同场景下的缓存与存储需求.同事redis的诸多高层级功能使其可以胜任消息队列,任务队列等不 ...

  3. Redis学习笔记之Redis中5种数据结构的使用场景介绍

    原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 redis 中一共有5种数据结构 ...

  4. Redis学习笔记之Redis单机,伪集群,Sentinel主从复制的安装和配置

    0x00 Redis简介 Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值 ...

  5. Redis学习笔记(4) Redis事务、生存时间及排序

    1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次 ...

  6. StackExchange.Redis学习笔记(一) Redis的使用初探

    Redis Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化. 与其它键值数据存储相比,Redis有一组相对丰富的数据类型. Redis可以将数据复制到任意数量的从机中 Redis的安装 官 ...

  7. redis学习笔记(三)——redis的命令大全总结

    总结了一些redis五种存储类型的常用命令以及一些通用操作命令,不是很全,是在学习的时候将学到的做了个汇总,使用的时候可以查一下. 笔记写在表格里面了,不好粘贴.......后面的直接截图了..... ...

  8. Redis学习笔记(3) Redis基础类型及命令之二

    1. 集合类型 集合类型与列表类型有很多相似之处,但二者的区别在于:前者具有唯一性,但不具有有序性:后者具有有序性,但不具有唯一性.集合类型的常用操作是向集合中加入或删除元素.判断某个元素是否存在等, ...

  9. Redis学习笔记(2) Redis基础类型及命令之一

    1. 基础命令 (1) 获取符合规则的键名列表 格式为:KEYS pattern 其中pattern表示支持通配符 # 建立一个名为bar的键 > SET bar OK # 获取Redis所有键 ...

  10. Redis学习笔记~StackExchange.Redis实现分布式Session

    回到目录 对于多WEB的环境现在已经是必须的了,很难想像一台WEB服务器面对百万并发的响应,所以,我们需要多台WEB服务器集群合作,来缓解这种高并发,高吞吐的场景,而对于多WEB的场景又会有个问题出现 ...

随机推荐

  1. C#进阶系列——DDD领域驱动设计初探(四):WCF搭建

    前言:前面三篇分享了下DDD里面的两个主要特性:聚合和仓储.领域层的搭建基本完成,当然还涉及到领域事件和领域服务的部分,后面再项目搭建的过程中慢慢引入,博主的思路是先将整个架构走通,然后一步一步来添加 ...

  2. [转]Java线程安全总结

    最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣.已经拟好了提纲,大概分为这几个主题: java线程安全,java垃圾收集,java并发包详细介绍,java profi ...

  3. Hadoop---Google MapReduce(转)

    1. MapReduce是干啥的 因为没找到谷歌的示意图,所以我想借用一张Hadoop项目的结构图来说明下MapReduce所处的位置,如下图. Hadoop实际上就是谷歌三宝的开源实现,Hadoop ...

  4. centos虚拟机网络桥接配置

    1.虚拟机设置->网络适配器->选择桥接模式->重启虚拟机 2.使用命令进行配置IP地址 (引用别人的配置命令) 修改/etc/sysconfig/network-scripts 目 ...

  5. Object Removal by Exemplar-Based Inpainting 概括(附源码)

    关于这篇论文:其是采用基于样例的图像修复,通俗地讲就是图像其他部分的采样信息去填补遮挡区域,其与使用扩散方法的图像修补方法相比,不会产生模糊效应. 论文中涉及到的几个参数     Ω:要修补的区域 δ ...

  6. COGS14. [网络流24题] 搭配飞行员

    [问题描述]     飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞 ...

  7. 用Python建立最简单的web服务器

    利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m ...

  8. 【Unity3D】AR应用中,关于东南西北方位的判断。

    这篇文章的应用场景是这样子的: 首先我们要做的是一个带有LBS定位服务(比如高德地图.百度地图等)AR功能,在这个场景中,会有一些地图上的”点“(如派出所.学校)是我们需要显示在我们的AR镜头上的,如 ...

  9. Math类

    Math类:用于执行基本数学运算的方法 方法: public static int abs(int a):绝对值 public static double ceil(double a):向上取整   ...

  10. ImageView的常用属性

    ImageView的一些常用属性,并且这些属性都有与之对应的getter.setter方法: android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片 ...