Redis实现任务队列(二)

概述

在处理Web客户端发送的命令请求时,某些操作的执行时间可能会比我们预期的更长一些。通过将待执行任务的相关信息放入队列里面,并在之后对队列进行处理,用户可以推迟执行那些需要一段时间才能完成的操作,这种将工作交给任务处理器来执行的做法称为任务队列。

延迟任务

    使用列表结构可以实现只能执行一种任务的队列,也可以实现通过调用不同回调函数来执行不同的任务队列,甚至还可以实现简单的优先级队列,但是有些时候,这些特性还不足以满足我们的需求。比如说:我们需要延迟处理某个队列,而不是立即就开始执行。

    有几种不同的方法可以为队列中的任务添加延迟性质,以下是三种最直接了当的方法。

    1、在任务信息中包含任务的执行时间,如果工作进程发现任务的执行时间尚未来临,那么它将在短暂等待之后,把任务重新推入队列里面。

    2、工作进程使用一个本地的等待列表来记录所有需要在未来执行的任务,并在每次进行while循环的时候,检查等待列表并执行那些已经到期的任务。

    3、把所有需要在未来执行的任务都添加到有序集合里面,并将任务的执行时间设置为分值,另外再使用一个进程来查找有序集合里面是否存在可以立即执行的任务,如果有的话,就从有序集合里面移除那个任务,并将它添加到适当的任务队列里面。

    因为无论是进行短暂的等待,还是将任务重新推入队列里面,都会浪费工作进程的时间,所以我们不会采用第一种方法。此外,因为工作进程可能会因为崩溃而丢失本地记录的所有带执行任务,所以我们也不会采用第二种方法。最后没因为使用有序集合的第三种方法最简单和直接,所以我们将采取这一方法。

    有序集合队列存储的每个被延迟的任务都是一个包含4个值的json列表。这4个值分别是:唯一标识符、处理任务的队列的名字,处理任务的回调函数的名字、传给回调函数的参数。在有序集合里面,任务的分值会被设置为任务的执行时间,而立即可执行的任务将被直接插入任务队列里面。


图5  将任务推入任务队列

    因为所有被延迟的任务都存储在同一个有序集合队列里面,所以程序只需要获取有序集合里面排名第一的元素以及该元素的分值就可以了:如果队列里没有任何任务,或者任务的执行时间尚未来临,那么程序将在短暂等待之后重试,如果任务的执行时间已到,那么程序将更具任务包含的标识符来后去一个细粒度锁,接着从有序集合里面移除要被执行的任务,并将它添加到适当的任务队列里面。


图6 任务入队列


图7 获得锁


图8 释放锁
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 180,090评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,006评论 19 139
  • 文/丁水汀 其实没有任何灵感,只知道睡不着写篇文章会好。窗外没有空灵的静谧,霓虹灯耀眼,夜生活吵闹。而我假装生活很...
    丁水汀阅读 334评论 0 1
  • 今晚过的时间有点漫长,我花了两个半小时,很耐心地听完了一整场“企业式简历制作”讲座。战线太长,把我听饿了。[骷髅]...
    Chosing_春幸阅读 500评论 0 0
  • 老而不死是为贼,多指无德朽木之流,妄活六旬有余,心无仁慈之念,岁月难改无耻本性,苍髯老贼如断脊狂犬,当一棍了之!
    虢士无伤阅读 295评论 0 0

友情链接更多精彩内容