nbsp; 解决方案:定义一个任务队列,作为生产者的页面进程负责添加任务到队列中,而作为消费者的邮件发送进程负责不断的从队列中获取任务进行处理。
任务队列的好处: |
1、 松耦合。生产者和消费者无需知道彼此的实现细节,只需要约定好任务对象的描述格式。 2、 易于扩展。可增加多个分布在不同服务器上的消费者来降低单台服务器的负载。 |
4.4.2 通过redis列表类型实现任务队列
思路:定义一个列表类型键作为任务队列,生产者通过LPush命令添加任务到队列中,消费者不断的使用Rpop命令从队列中取出任务来处理。消费者伪码如下:
BRPop list [list2 …] timeout BLPop …… |
描述:同时检测多个列表类型键,移出并获取列表的最后一个元素,如果列表中没有元素则会阻塞列表直到等待超时或发现可弹出元素为止;如果多个键都有元素则按照从左到右的顺序取第一个键中的第一个元素。timeout设置为”0”表示不限制等待时间。 返回值:假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。 |
4.4.3 优先级队列
需求:博客系统存在两种任务,即新邮箱请求订阅时发送确认邮件的任务,以及发布新文章后发送通知邮件给所有已订阅邮箱的任务。现在需要实现优先级队列,当发送确认邮件任务和发送通知邮件任务同时存在时,优先执行前者。
4.4.4 “发布/订阅”模式
publish channel msg |
描述:发布者给指定频道发布消息,发出去的消息不会被持久化,客户端订阅一个频道后只能收到后续发布到该频道的消息,之前发送的就收不到了。 返回值:接收到这条消息的订阅者数量 |
subscribe channel [channel2 …] |
描述:subscribe用于订阅者订阅指定频道,执行subscribe命令后客户端会进入订阅状态,处于此状态下的客户端不能使用除了subscribe、unsubscribe、psubscribe、unsubscribe这4个属于”发布/订阅”模式的命令之外的命令,否则会报错。 |
unsubscribe [channel channel2 …] |
用于订阅者取消订阅指定频道,如果不指定则会取消订阅所有频道。 |
4.4.5 按照规则订阅
PSUBSCRIBE pattern [pattern ...] |
PSUBSCRIBE命令用于订阅者订阅一个或多个符合给定模式的频道。用psubscribe命令进入订阅模式后,如果收到消息,返回值会包含4个值;第一个值为”pmessge”,表示这条消息是通过psubscribe命令订阅频道而收到的;第二个值表示订阅时使用的pattern;第三个值表示实际收到消息的频道名称,第四个值即为消息内容。 |
pUNsubscribe [pattern pattern2 …] |
PSUBSCRIBE用于退订指定的规则,如果没有指定参数,则会退订所有规则。 |
4.5管道
往返时延:redisClient向redis发送命令耗时 + redis向redisClient返回命令执行结果耗时 |
redis底层对管道提供了支持,通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,管道通过减少redisClient与redis的通信次数来实现降低往返时延累计值的目的。当一组命令中所有命令都不依赖于之前命令的执行结果时,就可以将这组命令一起通过管道发出。 |