分布式异步摆摊攻略 [Celery]

张大胖有个同学叫小A,毕业后在学校门口支了个炒饭摊头,为学弟学妹们提供美食成了他的事业。

小A的炒饭手艺可是一绝,不仅色香味俱全,更凭一道拿手的 “香芹炒饭” 成为了黑暗料理界的一哥,每到深夜,摊前总围着抵制不住美食诱惑前来买夜宵的学生们,小生意也算是红火。

可是好景不长,学弟学妹们一届比一届懒,大家伙不愿意大冬天的跑这么远,宁愿多加两块钱外送费在宿舍点起了外卖。这可把小A愁坏了,他就一个人,只好接完一单立马炒出一份,然后马不停蹄的送到宿舍去,回来继续接单炒下一份。

“这效率也太低了,一个晚上只能卖出不到 10 份,这还不够摊位成本的呢。我的事业可算是走到尽头了,哎!” 小A找张大胖倾诉着自己的苦恼。

张大胖无奈的说:“哥们,你就一个人,能做成这样已经很不容易啦。现在已经不是单打独斗的年代了,你真想把这炒饭事业做下去,得组建团队一起干才行。”


分工,异步处理

小A觉得张大胖说的不无道理,于是请来了三个好朋友,这三人分别是 Redis、大w 和 小w,几人分工如下:

  • 小A只负责接单和炒饭,打包好贴上纸条写明订单号以及派送地址,交给 Redis。
  • Redis 负责看管好所有 “待派送” (也称作 inqueue 状态) 的包裹。
  • 大w和小w是俩兄弟,他们的工作内容是相同的。从 Redis 那里领取待派送的包裹,送到客户手上,然后回来继续领取包裹,如果包裹全都派送完了,就在 Redis 身边等着直到有新的待派送的包裹出现。他俩有个共同的昵称叫 worker。

任务分配好,大家伙热火朝天的干了起来,小A还给他们团队起了个名字叫 Celery。果然团结就是力量,大家分工得当配合默契,生意又重新红红火火起来了。


反馈,处理异常

可惜好景不长,新的问题出现了,由于小w是个冒失鬼,经常配送途中把包裹弄丢丢了,这样经常有客户等了一个晚上都没等到他的夜宵,小A收到的投诉越来越多,得想个办法解决才行。

于是小A决定改进一下工作流程:让 Redis 每次交给 worker 一个包裹后,同时拿出小本本,在 “派送中” (也可被称作 unacked 状态) 这一页填写上该包裹的订单号。每当 worker 完成一单派送后,将订单号反馈告知 Redis(这个动作被称作 ack),Redis 就从小本本上将这条派送中的记录删去。

这样,只要发现有某个订单号一直处于 “派送中” 状态,并且 worker 都没在派送它,可以断定这个包裹丢了。小A就立马做一份一样的交给 Redis,等待重新派送。如此一来客户需要多等待一会儿,但今晚是一定能吃到香美的炒饭的!

小A很满意自己的设计,第二天就让 Redis 和 worker 小组按照他的方案做起来。效果确实很不错,再也没有收到客户的投诉了。


定时任务

爱吃小A炒饭的回头客越来越多,其中有不少人向小A提出 “预约送餐服务” 的需求,比如提前在8点下好单,预约到9点再派送上门。

这可难不倒小A,只要在订单信息中加一栏 “派送时间” 一同放入交给了Redis 的包裹中就行了,worker 从 Redis 处领取到待派送的包裹后先查看派送时间,如果是 “立即派送” 就立马将这个包裹送出;如果还没到派送时间的话,就先不送出,等到了预定的时间再进行派送。

预约送餐的新服务正式施行,获得学弟学妹的一致好评。


perStop,优雅的结束 worker

好日子没过多久,小w又闹出幺蛾子了,他新交了个女朋友,经常外卖送到一半就溜号去约会了,手头上的包裹也顺手给扔了,这可耽误整个团队的工作。

小A召集大家伙开会,让大家伙献计献策解决这个问题,Redis 拍桌子道:“小w,你这家伙也太普靠谱啦,我建议你还是回家洗洗睡吧,咱再找其他人来接替你!”

大w为弟弟辩解:“我这弟弟虽然有点冒失和不懂事,但毕竟是自己人啊,如果再换个人,就一定能比小w干的好?”

小w扭捏的说道:“对不起,是我的错,给大家添麻烦了。我提个方案,你们看行不行,我们 worker 在领取到包裹后在 Redis 那里都会有 unacked 记录嘛,如果在派送过程中临时有事要离开,就将 unacked 的包裹全还给 Redis,Redis 将这些包裹重新放回待派送区域,同时将这些 unacked 记录删除。”

Redis 可不开心了:“这不是增加我的工作量嘛,你们的错,要我来背锅,也太欺负人啦!”

小A站出来调停:“我觉得小w说的方案可行,就按这么做吧。Redis 你能者多劳,辛苦一些,回头给你加工资。”

就这样解决了眼下所有的问题,小A的炒饭事业终于正式扬帆起航了。


后记

直到有一天,有个名叫 RabbitMQ 的外卖小哥前来拜访,问了 Redis 一个问题:“你考虑过万一 worker 派送途中遇到急事离开,没告知你,也没把包裹还给你。那时你该咋办吗?” Redis 面露难色不足如何作答。
RabbitMQ 笑而不语,留下一张名片给小A后,头也不回的走了...

PS:
1、小A的名字是致敬 celery 的作者 Ask Solem Hoel
2、参考了我曾经写的一篇简书文章: https://www.jianshu.com/p/52552c075bc0

推荐阅读更多精彩内容

  • redis集群分为服务端集群和客户端分片,redis3.0以上版本实现了集群机制,即服务端集群,3.0以下使用客户...
    hadoop_null阅读 1,035评论 0 6
  • 1.定义: Celery是一个异步的任务队列(也叫做分布式任务队列) 2.工作结构 Celery分为3个部...
    四号公园_2016阅读 24,176评论 5 60
  • 创建产品目录模型(models) image = models.ImageField(upload_to='pro...
    lijun_m阅读 278评论 0 0
  • 翻 译 者(付费):Paul(保尔)、MS.Liu(刘女士)等 中 英 文 校 对:阿若兰(本人QQ号279134...
    code_w阅读 972评论 1 2
  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 6,857评论 0 8