Redis也可以作为任务队列。任务队列顾名思义,就是“传递任务的队列”。任务队列与消息队列什么区别呢?任务队列是逻辑模型,而消息队列是通信模型,两者是不同层次的抽象,用消息队列可以实现任务队列。 与任务队列进行交互的实体有两类,一类是生产者(producer),一类是消费者(consumer)。生产者会将需要处理的任务放入任务队列中,而消费者则不断地从任务队列中读入任务信息并执行。 使用任务队列可以达到松耦合的效果,生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式。这使得生产者和消费者可以由不同的团队使用不同的编程语言编写。 而且这种模型下,消费者可以很容易地进行扩展,并可以分布在不同的服务器,降低单台服务器的负载。 使用列表实现任务队列Redis的列表类型支持从一边PUSH、从另一边POP的操作,用作队列非常合适。只需生产者通过LPUSH命令将任务加入列表中,另一边让消费者不断使用RPOP命令从列表中取出即可。但不希望消费者不停RPOP,可以用BRPOP改进。BRPOP在列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新元素加入。 BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位是秒。当超过了此时间仍然没有获得新元素的话就会返回nil。超时时间设置为0时,如果没有新元素加入列表就会永远阻塞下去。 开启多个客户端为了测试消息通知,可以开启多个redis-cli实例。
redis-server命令可以启动redis server。
在实例A中输入:
接下来实例A会一直处于阻塞状态。然后在实例B中向队列加入元素:
这时马上就可以在实例A中看到返回结果,同时可以验证queue中刚刚加入的元素已经被取走了。 优先级队列BRPOP命令可以同时接收多个键,如:
这时它会同时检测这几个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素则会从该键中弹出元素。 借助这些特性可以实现优先级队列,queue:1 queue:2 queue:3三个队列中,queue:1的优先级最高,这个队列中的任务会优先被消费。 比如在一个网站中,向用户发送的邮件中账号激活邮件的优先级比活动推广邮件的优先级高,这时就可以将这两种邮件放在不同的队列,用BRPOP来优先发送激活邮件。 “发布/订阅”模式除了实现任务队列外,Redis还提供了一组命令可以让开发者实现“发布/订阅”(publish/subscribe)模式。“发布/订阅”模式同样可以实现进程间的消息传递。 在redis-cli实例A发布消息:
PUBLISH命令的返回值表示接收到这条消息的订阅者数量。发出去的消息不会被持久化,客户端订阅channel.1后只能收到后续发布到该频道的消息,之前发送的是收不到的。 在redis-cli实例B订阅channel.1
SUBSCRIBE命令可以同时订阅多个频道。 执行SUBSCRIBE命令后客户端会进入订阅状态,处于此状态下客户端只能使用属于“发布/订阅”模式的命令,这些命令有SUBSCRIBE/UNSUBSCRIBE/PSUBSCRIBE/PUNSUBSCRIBE。 但在redis-cli中进入订阅状态后是无法退出到非订阅状态的,只能关闭cli。 实例B已经订阅了channel.1,这时如果再从实例A向channel.1发布消息msg1,实例B就会收到下面的响应:
第一行是消息类型,消息类型的取值有subscribe/message/unsubscribe。 按照规则订阅除了可以使用SUBSCRIBE命令订阅指定名称的频道外,还可以使用PSUBSCRIBE命令按照按照指定的规则订阅多个频道。如:
订阅规则支持glob风格通配符格式,channel.中可以匹配任意数量的字符。 PUNSUBSCRIBE命令可以退订指定的规则
如果没有指定pattern参数,则会退订所有由PSUBSCRIBE订阅的规则。 使用PUNSUBSCRIBE命令只能退订通过PSUBSCRIBE命令订阅的规则,不会影响直接通过SUBSCRIBE命令订阅的频道;同样UNSUBSCRIBE命令也不会影响通过PSUBSCRIBE命令订阅的规则。 |
|