• redis发布订阅


    前言

      Redis的发布与订阅模型在许多编程语言中都有实现,也就是我们常说的设计模式中的一种——观察者模式。在一些应用场合,例如发送方不是以固定频率发送消息,如果接收方频繁去资讯发布方,这种操作无疑是很麻烦并且不友好的。

      而订阅发布模型,订阅者只需要订阅注册某个频道就好了,当有消息发送过来的时候,会通过订阅的频道接收。优势在于把耦合点独立分离处理,作为发布方和接收方的中介,实现了发布方和接收方的分离。

      订阅与发布系统是Redis的一个高级属性,多个客户端可以同时订阅同一个频道,类似广播的机制。所不同的是,一个客户端可以同时订阅多个频道。也就是Redis客户端可以订阅任意数量的频道。

      下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

      当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

     

     实现原理

      服务器中维护着一个pubsub_channels字典,所有的频道和订阅关系都存在这里。字典的键为频道的名称,而值为订阅频道的客户端链表。

    1. 当有新的客户端订阅某个频道时,会发生一下两种情况中的一种:
      • 如果频道已经存在,则新的客户端会添加到pubsub_channels对应频道的链表末尾;
      • 如果频道原本不存在,则会为频道创建一个键,该客户端成为链表的第一个元素。

      2. 当客户端退订一个频道的时候,pubsub_channels对应键的链表会删除该客户端;

      3. 发送消息时,服务器会遍历pubsub_channels中对应键的链表,向每个客户端发送消息。

      服务器还维护着一个pubsub_patterns链表,链表的pattern属性记录了被订阅的模式,而Client属性记录了订阅模式的客户端。

    1. 当有新的客户端订阅某个模式时,进行如下步骤:
      1. 创建一个链表节点,pattern属性记录订阅的模式,Client记录订阅模式的客户端;
      2. 将这个链表节点添加到pubsub_patterns链表中。
    2. 当一个客户端退订某个模式时,服务器遍历pubsub_patterns链表,找到对应的pattern同时也是对应的Client客户端节点,将该节点删除;
    3. 发送信息时,服务器遍历pubsub_channels,查找与channels频道相匹配的模式,将消息发送给订阅了这些模式的客户端。

    Redis订阅系统的优势:

    1. 当一个客户端向频道发送一个信息,订阅了同一频道/模式的多个客户端可以同时接收到信息,类似广播的机制;
    2. 便于Sentinel哨兵与服务器之间的通信并进行监控。

    Redis发布订阅命令

    1. psubscribe:订阅一个或多个符合给定模式的频道。

    每个模式以 * 作为匹配符,比如:it* 匹配所有以 it 开头的频道(如,it.news,it.blog,it.tweets等)。news.*匹配所有以news.开头的频道。

    支持的模式(patterns)有:

    h?llo subscribes to hello, hallo and hxllo
    h*llo subscribes to hllo and heeeello
    h[ae]llo subscribes to hello and hallo, but not hillo
    

    如果想输入普通的字符,可以在前面添加  

    语法:

    PSUBSCRIBE pattern [pattern ...]

    实例:

     
    127.0.0.1:6379> psubscribe mychannel h?llo h*llo h[ae]ll0
    Reading messages... (press Ctrl-C to quit)
    1) "psubscribe"
    2) "mychannel"
    3) (integer) 1
    1) "psubscribe"
    2) "h?llo"
    3) (integer) 2
    1) "psubscribe"
    2) "h*llo"
    3) (integer) 3
    1) "psubscribe"
    2) "h[ae]ll0"
    3) (integer) 4

    2. publish:将信息发送到指定的频道

    语法:

    PUBLISH channel message  

    返回值:接收到信息的订阅者数量

    实例:

    127.0.0.1:6379> publish mychannel 'mychannel message'
    (integer) 1
    127.0.0.1:6379> publish hello 'hello message'
    (integer) 2
    127.0.0.1:6379> publish hell0 'hell0 message'

    3. pubsub:查看订阅与发布系统的状态,它由数个不同格式的子命令组成

    语法:

    PUBSUB <subcommand> [argument [argument ...]]  

    pubsub channels [pattern]:列出当前活跃的频道列表,活跃是指信道含有一个或多个订阅者(不包括从模式接收订阅的客户端),如果pattern未提供,所有的信道都会被列出,否则值列出匹配上指定全局-类型模式的信道被列出。

    返回值:活跃的频道列表,或者符合指定模式的频道。

    实例:

    127.0.0.1:6379> pubsub channels mychannel
    (empty array)

    PUBSUB NUMSUB [channel-1 ... channel-N]: 列出指定频道的订阅者个数(不包括订阅模式的客户端订阅者)。

    返回值:频道的列表和每个列表中订阅者的个数,格式为:频道,个数,频道,个数,...简单的列表。

    注意,不指定任何频道而直接调用这个命令也是可以的,此时,命令只返回一个空列表

    实例:

    127.0.0.1:6379> pubsub numsub
    (empty array)
    127.0.0.1:6379> pubsub numsub mychannel
    1) "mychannel"
    2) (integer) 0

    pubsub numpat:返回订阅模式的数量(使用命令psubscribe命名实现)。注意,这个命令返回的不是订阅模式的客户端的数量,而是客户端订阅的所有模式的数量总和。

    返回值:客户端订阅的所有模式的总和。

    实例:

    127.0.0.1:6379> pubsub numpat
    (integer) 4

    4. punsubscribe [ pattern [pattern ...]]:退订所有给定模式的频道。

    说明:

    该命令指示客户端退订指定模式,如果没有指定模式则退出所有的模式。

    如果没有模式被指定,即一个无参的punsubscribe调用被执行,那么客户端使用psubscribe命令订阅的所有模式都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的模式。

    返回值:这个命令在不同的客户端中有不同的表现。

    实例:

    127.0.0.1:6379> punsubscribe mychannel
    1) "punsubscribe"
    2) "mychannel"
    3) (integer) 0
    127.0.0.1:6379> punsubscribe
    1) "punsubscribe"
    2) (nil)
    3) (integer) 0
    127.0.0.1:6379> 

    5. subscribe:订阅给定的一个或多个频道信息

    一旦客户端进入订阅状态,客户端就只可以接受订阅相关的命令SUBSCRIBEPSUBSCRIBEUNSUBSCRIBEPUNSUBSCRIBE除了这些命令,其他命令一律失效。

    语法:

    SUBSCRIBE channel [channel ...]  

    返回值:接收到的信息

    实例:

    127.0.0.1:6379> subscribe mychannel
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "mychannel"
    3) (integer) 1
    1) "message"
    2) "mychannel"
    3) "mychannel message"

    6. unsubscribe: 退订给定的频道。

    指示客户端退订给定的频道,若没有指定频道,则退订所有频道.

    如果没有频道被指定,即,一个无参数的 UNSUBSCRIBE 调用被执行,那么客户端使用 SUBSCRIBE 命令订阅的所有频道都会被退订。 在这种情况下,命令会返回一个信息,告知客户端所有被退订的频道。

    语法:

     UNSUBSCRIBE channel [channel ...]  

    返回值:这个命令在不同的客户端中有不同的表现。

    实例:

    127.0.0.1:6379> unsubscribe mychannel
    1) "unsubscribe"
    2) "mychannel"
    3) (integer) 0
    127.0.0.1:6379> unsubscribe
    1) "unsubscribe"
    2) (nil)
    3) (integer) 0

    Sentinel哨兵中的应用

    Sentinel服务器与Master服务器/Slave服务器之间的订阅发布系统是Sentinel监控过程的一个重要环节,通过订阅发布系统达到监控服务器状态的作用。其运行原理与上面的客户端服务器之间的订阅机制无太大区别,都是基于网络连接的数据传输。Sentinel之间的通信也是通过Sentinel与服务器之间的这个订阅发布系统实现的,一个Sentinel通过服务器的频道发送信息,其他Sentinel就会接收到。

  • 相关阅读:
    JMF:Screen Grabber [DataSource]
    ImageUtilities.loadImage第二个参数的说明
    PipeStateListener和PipeEventListener
    as3 htmlText常用标签
    jsfl批量导出swf
    java socket安全策略文件
    模拟EventCenter,flash自带的事件机制的一个解耦框架,callback回调方式用于模块之间的通信
    flashDevelop快捷键和几个实用的插架
    as3 用StyleSheet css 设置文本样式
    as3 位图九宫格
  • 原文地址:https://www.cnblogs.com/huige185/p/14227312.html
Copyright © 2020-2023  润新知