張大胖有個(gè)同學(xué)叫小A,畢業(yè)后在學(xué)校門口支了個(gè)炒飯攤頭趋翻,為學(xué)弟學(xué)妹們提供美食成了他的事業(yè)芹壕。
小A的炒飯手藝可是一絕窟绷,不僅色香味俱全锯玛,更憑一道拿手的 “香芹炒飯” 成為了黑暗料理界的一哥,每到深夜兼蜈,攤前總圍著抵制不住美食誘惑前來買夜宵的學(xué)生們攘残,小生意也算是紅火。
可是好景不長为狸,學(xué)弟學(xué)妹們一屆比一屆懶肯腕,大家伙不愿意大冬天的跑這么遠(yuǎn),寧愿多加兩塊錢外送費(fèi)在宿舍點(diǎn)起了外賣钥平。這可把小A愁壞了,他就一個(gè)人姊途,只好接完一單立馬炒出一份涉瘾,然后馬不停蹄的送到宿舍去,回來繼續(xù)接單炒下一份捷兰。
“這效率也太低了立叛,一個(gè)晚上只能賣出不到 10 份,這還不夠攤位成本的呢贡茅。我的事業(yè)可算是走到盡頭了秘蛇,哎!” 小A找張大胖傾訴著自己的苦惱顶考。
張大胖無奈的說:“哥們赁还,你就一個(gè)人,能做成這樣已經(jīng)很不容易啦【匝兀現(xiàn)在已經(jīng)不是單打獨(dú)斗的年代了艘策,你真想把這炒飯事業(yè)做下去,得組建團(tuán)隊(duì)一起干才行渊季∨竽瑁”
分工,異步處理
小A覺得張大胖說的不無道理却汉,于是請(qǐng)來了三個(gè)好朋友驯妄,這三人分別是 Redis、大w 和 小w合砂,幾人分工如下:
- 小A只負(fù)責(zé)接單和炒飯青扔,打包好貼上紙條寫明訂單號(hào)以及派送地址,交給 Redis。
- Redis 負(fù)責(zé)看管好所有 “待派送” (也稱作 inqueue 狀態(tài)) 的包裹赎懦。
- 大w和小w是倆兄弟雀鹃,他們的工作內(nèi)容是相同的。從 Redis 那里領(lǐng)取待派送的包裹励两,送到客戶手上黎茎,然后回來繼續(xù)領(lǐng)取包裹,如果包裹全都派送完了当悔,就在 Redis 身邊等著直到有新的待派送的包裹出現(xiàn)傅瞻。他倆有個(gè)共同的昵稱叫 worker。
任務(wù)分配好盲憎,大家伙熱火朝天的干了起來嗅骄,小A還給他們團(tuán)隊(duì)起了個(gè)名字叫 Celery
。果然團(tuán)結(jié)就是力量饼疙,大家分工得當(dāng)配合默契溺森,生意又重新紅紅火火起來了。
反饋窑眯,處理異常
可惜好景不長屏积,新的問題出現(xiàn)了,由于小w是個(gè)冒失鬼磅甩,經(jīng)常配送途中把包裹弄丟丟了炊林,這樣經(jīng)常有客戶等了一個(gè)晚上都沒等到他的夜宵,小A收到的投訴越來越多卷要,得想個(gè)辦法解決才行渣聚。
于是小A決定改進(jìn)一下工作流程:讓 Redis 每次交給 worker 一個(gè)包裹后,同時(shí)拿出小本本僧叉,在 “派送中” (也可被稱作 unacked 狀態(tài)) 這一頁填寫上該包裹的訂單號(hào)奕枝。每當(dāng) worker 完成一單派送后,將訂單號(hào)反饋告知 Redis(這個(gè)動(dòng)作被稱作 ack)彪标,Redis 就從小本本上將這條派送中的記錄刪去倍权。
這樣,只要發(fā)現(xiàn)有某個(gè)訂單號(hào)一直處于 “派送中” 狀態(tài)捞烟,并且 worker 都沒在派送它薄声,可以斷定這個(gè)包裹丟了。小A就立馬做一份一樣的交給 Redis题画,等待重新派送默辨。如此一來客戶需要多等待一會(huì)兒,但今晚是一定能吃到香美的炒飯的苍息!
小A很滿意自己的設(shè)計(jì)缩幸,第二天就讓 Redis 和 worker 小組按照他的方案做起來壹置。效果確實(shí)很不錯(cuò),再也沒有收到客戶的投訴了表谊。
定時(shí)任務(wù)
愛吃小A炒飯的回頭客越來越多钞护,其中有不少人向小A提出 “預(yù)約送餐服務(wù)” 的需求,比如提前在8點(diǎn)下好單爆办,預(yù)約到9點(diǎn)再派送上門难咕。
這可難不倒小A,只要在訂單信息中加一欄 “派送時(shí)間” 一同放入交給了Redis 的包裹中就行了距辆,worker 從 Redis 處領(lǐng)取到待派送的包裹后先查看派送時(shí)間余佃,如果是 “立即派送” 就立馬將這個(gè)包裹送出;如果還沒到派送時(shí)間的話跨算,就先不送出爆土,等到了預(yù)定的時(shí)間再進(jìn)行派送。
預(yù)約送餐的新服務(wù)正式施行诸蚕,獲得學(xué)弟學(xué)妹的一致好評(píng)步势。
perStop,優(yōu)雅的結(jié)束 worker
好日子沒過多久背犯,小w又鬧出幺蛾子了立润,他新交了個(gè)女朋友,經(jīng)常外賣送到一半就溜號(hào)去約會(huì)了媳板,手頭上的包裹也順手給扔了,這可耽誤整個(gè)團(tuán)隊(duì)的工作泉哈。
小A召集大家伙開會(huì)蛉幸,讓大家伙獻(xiàn)計(jì)獻(xiàn)策解決這個(gè)問題,Redis 拍桌子道:“小w丛晦,你這家伙也太普靠譜啦奕纫,我建議你還是回家洗洗睡吧,咱再找其他人來接替你烫沙!”
大w為弟弟辯解:“我這弟弟雖然有點(diǎn)冒失和不懂事匹层,但畢竟是自己人啊,如果再換個(gè)人锌蓄,就一定能比小w干的好升筏?”
小w扭捏的說道:“對(duì)不起,是我的錯(cuò)瘸爽,給大家添麻煩了您访。我提個(gè)方案,你們看行不行剪决,我們 worker 在領(lǐng)取到包裹后在 Redis 那里都會(huì)有 unacked 記錄嘛灵汪,如果在派送過程中臨時(shí)有事要離開檀训,就將 unacked 的包裹全還給 Redis,Redis 將這些包裹重新放回待派送區(qū)域享言,同時(shí)將這些 unacked 記錄刪除峻凫。”
Redis 可不開心了:“這不是增加我的工作量嘛览露,你們的錯(cuò)荧琼,要我來背鍋,也太欺負(fù)人啦肛循!”
小A站出來調(diào)停:“我覺得小w說的方案可行铭腕,就按這么做吧。Redis 你能者多勞多糠,辛苦一些累舷,回頭給你加工資〖锌祝”
就這樣解決了眼下所有的問題被盈,小A的炒飯事業(yè)終于正式揚(yáng)帆起航了。
后記
直到有一天搭伤,有個(gè)名叫 RabbitMQ 的外賣小哥前來拜訪只怎,問了 Redis 一個(gè)問題:“你考慮過萬一 worker 派送途中遇到急事離開,沒告知你怜俐,也沒把包裹還給你身堡。那時(shí)你該咋辦嗎?” Redis 面露難色不足如何作答拍鲤。
RabbitMQ 笑而不語贴谎,留下一張名片給小A后,頭也不回的走了...
PS:
1季稳、小A的名字是致敬 celery 的作者 Ask Solem Hoel
2擅这、參考了我曾經(jīng)寫的一篇簡書文章: http://www.reibang.com/p/52552c075bc0