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 !"