1 任务队列
当页面需要进行如发送邮件,复杂数据运算等耗时较长的操作会阻塞页面的渲染。所以为了避免用户等待太久,应该使用独立的线程完成这类操作。
与任务队列进行交互的实体有两类,一类是生产者(producer),一类是消费者(consumer).
使用任务队列有如下好处
- 松耦合 生产者和消费者无需知道彼此实现细节,只要约定好任务的描述格式,这使得生产者和消费者可以由不同的团队使用不同的语言编写
- 易于扩展 消费者可以有多个,可以分布在不同的服务器上,可以降低单台服务器的负载
2 使用redis实现任务队列
如果要实现任务队列,只需要让生产者将任务使用LPUSH命令加入到某个键中,另一边让消费者不断地会用RPOP命令从该键从取出任务即可,伪代码如下
loop
$task = RPOR queue
if $task
# 如果任务队列中有任务则执行它
execute($task)
else
# 如果没有则等待1秒以免过于频繁的请求数据
wait 1 second
BRPOP命令和RPOP命令相似,唯一区别是当列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新元素加入,上段代码可以改写为
loop
$task = BRPOP queue,0
execute($task[1])
BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位秒。超过时间仍然没有获得新元素的话就会返回nIl。如果超时时间设置为0,那么表示不设置等待时间,若没有新元素加入队列则永远阻塞下去。
另外也提供了BLPOP(从队列左侧取出元素)
BRPOP 可以接收多个键,
3 优先级队列
略
4 发布订阅模式
发布/订阅模式同样可以实现进程间的消息传递,原理如下:
首先:发布/订阅模式包含两种角色,发布者和订阅者
订阅者可以订阅1到多个频道,发布者可以在指定的频道发布消息,所有订阅该频道的订阅者都会受到该消息
发布者发布的用法 是 PUBLISH channel message,示例如下
127.0.0.1:6379> PUBLISH channel1.1 hi
(integer) 0
返回值表示接收到这条消息的订阅者数量
发出的消息不会被持久化,订阅了这个频道的订阅者只能收到后续的消息,订阅之前的消息是收不到的
订阅者订阅的语法为SUBSCRIBE channel [channel...] 示例如下
127.0.0.1:6379> SUBSCRIBE channel1.1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1.1"
3) (integer) 1
1) "message"
2) "channel1.1"
3) "hi"
1) "message" # 消息类型
2) "channel1.1" # 订阅频道
3) "hello" # 返回消息
进入订阅状态,处于此状态下客户端不能使用除SUBSCRIBE,UNSUBSCRIBE,PSUBSCRIBE,PUNSUBSCRIBE之外的命令
消息类型有以下3个
- subscribe 表示订阅成功的反馈信息
- message 表示接收到的消息
- unsubscribe 表示成功取消订阅某个频道