在处理Web客户端发送的命令请求是,某些操作的执行时间可能会比我们预期的更长一些。通过将待执行任务的相关信息放入队列里面,并在之后对队列进行处理,用户可以推迟执行那些需要一段时间才能完成的操作,这种将工作交给任务处理器来执行的做法被称为任务队列(task queue)。
1.先进先出队列
这一节将介绍两种不同类型的任务队列,第一种队列会根据任务被插入队列的顺序来尽快地执行任务,而第二种队列则具有安排在未来某个特定时间执行的能力。
Redis的列表结构允许用户通过 RPUSH
和 LPUSH
以及 RPOP
和 LPOP
,从列表的两端推入和弹出元素。这次邮件队列将使用 RPUSH 命令来将待发送的邮件推入列表的右端,并且因为工作的进程除了发送邮件之外不需要执行其他工作,所以它将使用阻塞版本的弹出命令 BLPOP
从队列中弹出待发送的邮件,而命令的最大阻塞时限为30秒。
邮件入队
代码清单 sendSolEmailViaQueue() 函数
|
|
邮件出队
代码清单 processSoldEmailQueue() 函数
|
|
2. 多个可执行任务
- 在一些情况下,为每种任务单独使用一个队列的做法并不少见,但是在另外一些情况下,如果一个队列能够处理多种不同类型的任务,那么事情就会方便很多。
- 如下代码展示的工作进程会监视用户提供的多个队列,并从多个已知的已注册回调函数里面,选出一个函数来处理Json编码的函数调用。
BLPOP
命令和BRPOP
命令都允许用户给定多个列表作为弹出操作的执行对象:其中前者将弹出第一个非空队列的第一个元素,后者则会弹出第一个非空队列的最后一个元素。
|
|
3. 延迟任务
为了实现延迟执行的特性,修改现有的队列实现:
- 把所有需要在未来执行的任务都添加到有序集合里面,并将任务的执行时间设置为分值,
- 另外再使用一个进程来查找有序集合里面是否存在可以立即被执行的任务,如果有的话,就从有序集合里面移除那个任务,并将他添加到适当的任务队列里面。
|
|
3.2 从延迟执行队列拉取任务执行
- 因为Redis没有提供直接的方法可以阻塞有序集合直到元素的分值低于当前的UNIX时间戳为止,所以我们需要自己来查找有序集合里面分值低于当前UNIX时间戳的任务。
|
|
4. 主类:
|
|
5. 运行结果
在延迟时间到达之后出现结果
|
|