redis消息通知(任务队列/优先级队列/发布订阅模式)

时间:2022-05-07 15:27:14

1、任务队列

对于发送邮件或者是复杂计算这样的操作,常常需要比较长的时间,为了不影响web应用的正常使用,避免页面显示被阻塞,常常会将此类任务存入任务队列交由专门的进程去处理。

队列最基础的方法如下:

有新任务的时候,通过lpush推送任务到队列中......while(true){
    if(队列有无新任务)
        有,则rpop取出新任务
    else
        等待一段时间,避免频繁检查队列
}

对于上述的策略,redis有更有一些的方法,即使用BRPOP命令

有新任务的时候,通过lpush推送任务到队列中
......
while(true){
    BRPO取出新任务
    执行任务
}

如果队列中没有元素,则会阻塞列表直到等待超时或发现可弹出元素为止。假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。

brpop命令格式如:brpop 列表键名 等待时间

1)如果等待时间设置为0,则表示不限制等待时常。经测试,开启两个redis客户端连接,当客户端A被此命令阻塞时,另一个 客户端B王队列在推送任务,客户端A即刻取出该新任务。

2)如果设置了等待时间,则超时后会返回nil和等待时长。

2、优先级队列

按照上面所说,邮件任务可以通过队列处理,但邮件发送任务可能存在优先级的区别,对于验证码这类的邮件,优先级要高于订阅类的邮件,如果通过一个队列来处理,肯定是不合理的。幸运的是,redis考虑到了这一点,brpop可以支持多个键值。如设queue:verifycode.email为验证码邮件,queue:channel:email为订阅类邮件,则可以这么取出任务:

brpop queue:verifycode.email queue:channel:email 0

按照键值的排序从左至右,brpop会优先取出queue:verifycode.email的任务进行处理,如果该队列没有任务处理,则再取出优先级次之的队列任务。

3、发布/订阅模式

订阅频道tmpchannel。返回消息:2)表示订阅成功的频道名称 3)表示当前客户端订阅的频道数量:

> subscribe tmpchannel
Reading messages... (press Ctrl-C to quit)
) "subscribe"
) "tmpchannel"
) (integer) 

取消订阅。如果命令后不说明要取消订阅的频道名称,则会取消所有订阅。当3)是0的时候,表示当前退出了订阅状态。

> unsubscribe tmpchannel
) "unsubscribe"
) "tmpchannel"
) (integer) 

发布消息。返回消息:订阅者的数量:

> publish tmpchannel hello
(integer) 

待发布消息后,订阅者即可能收到发布者发布的信息。格式:2)表示频道 3)发布的消息:

) "message"
) "tmpchannel"
) "hello"

redis还支持glob通配符订阅频道,如:

psubscribe channel1.?*

该命令可订阅满足该glob通配符的所有频道。相对应的,取消订阅即用punsubscribe命令

punsubscribe channel1.?*

采用通配符订阅的客户端返回的信息格式如下:

) "pmessage"
) "chanel1.?*"
) "chanel1.2.3"
) "Hello World !"