阿里云
发表主题 回复主题
  • 580阅读
  • 0回复

Redis 发布订阅

级别: 小白
发帖
0
云币
-4
发布订阅(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写的简单的client。代码如下

import java.net.*;

import java.io.*;

public class PubSubTest

{

 public static void main(String[] args)

{

 String cmd =

args[0]+"\r\n";

 try

{

 Socket

socket = new

Socket("192.168.56.55",6379);

 

InputStream in =

socket.getInputStream();

 

OutputStream out = socket.getOutputStream();

 

out.write(cmd.getBytes());

//发送订阅命令

 

byte[] buffer = new

byte[1024];

 

while (true)

{

 

int readCount =

in.read(buffer);

 

System.out.write(buffer, 0,

readCount);

 

System.out.println("--------------------------------------");

 

}

 } catch (Exception e)

{

 }

 

}

}


代码就是简单的从命令行读取传过来的订阅命令,然后通过一个socket连接发送给redis server,然后进入while循环一直读取redis server传过来订阅的消息。并打印到控制台

1 首先编译并运行此java程序(我是win7下面运行的)

D:\>javac PubSubTest.java

D:\>java PubSubTest "subscribe

news.share

news.blog"

*3

$9

subscribe

$10

news.share

:1

*3

$9

subscribe

$9

news.blog

:2


--------------------------------------


2 启动redis-cli

redis> psubscribe news.*

Reading messages... (press

Ctrl-c to quit)

1. "psubscribe"

2. "news.*"

3. (integer) 1


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

redis> publish news.share "share a link

http://www.google.com"

(integer) 2

redis> publish

news.blog "I post a blog"

(integer) 2


4.查看两个订阅client的输出

此时java client打印如下内容

*3

$7

message

$10

news.share

$34

share a link

http://www.google.com

--------------------------------------

*3

$7

message

$9

news.blog

$13

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"


分析下

java client使用subscribe命令订阅news.share和news.blog两个通道,然后立即收到server返回的订阅成功消息,可以看出 redis的协议是文本类型的,这里不解释具体协议内容了,可以参考http://redis.io/topics/protocol或者http://terrylee.me/blog/post/2011/01/26/redis-internal-part3.aspx。这个报文内容有两部分,第一部分表示该socket连接上使用 subscribe订阅news.share成功后,此连接订阅通道数为1,后一部分表示使用subscribe订阅news.blog成功后,该连接订 阅通道总数为2。

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命令订阅多个通配符通道,如果一个消息匹配上了多个通道模式的话,会多次收到同一个消息。


jredis目前版本没提供pub/sub支持,不过自己实现一个应该也挺简单的。整个应用程序可以共享同一个连接。因为redis返回的消息报文中除了消息内容本身外还包括消息相关的通道信息,当收到消息后可以根据不同的通道信息去调用不同的callback来处理。

另外个人觉得redis的pub/sub还是有点太单薄(实现才用150行代码)。在安全,认证,可靠性这方便都没有太多支持。



发表主题 回复主题
« 返回列表
«12345678910»
共10页
上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: ECS是阿里云提供的什么服务? 正确答案:云服务器
上一个 下一个
      ×
      全新阿里云开发者社区, 去探索开发者的新世界吧!
      一站式的体验,更多的精彩!
      通过下面领域大门,一起探索新的技术世界吧~ (点击图标进入)

      版权声明

      开发者论坛为你提供“Redis 发布订阅”的内容,论坛中还有更多关于 发布订阅订阅2发布订阅内容耦合redis实现消息队列 的内容供你使用,该内容是网友上传,与开发者论坛无关,如果需要删除请联系zixun-group@service.aliyun.com,工作人员会在5个工作日内回复您。