星巴克是如何處理訂單的?
點(diǎn)擊上方藍(lán)色“程序猿DD”,選擇“設(shè)為星標(biāo)”
回復(fù)“資源”獲取獨(dú)家整理的學(xué)習(xí)資料!


來源:r6d.cn/6dyh
譯者序
本文翻譯自 2004 年的一篇文章: Starbucks Does Not Use Two-Phase Commit.
1. 請(qǐng)給我一杯熱巧克力(Hotto Cocoa o Kudasai)
剛結(jié)束了一次為期兩周的日本之旅。印象深刻的是數(shù)量多到難以置信的星巴克 —— 尤其是在 新宿和六本木地區(qū)。在等待咖啡制作時(shí),我開始思考星巴克是如何處理訂單的。
與大多數(shù)商業(yè)公司一樣,星巴克主要關(guān)心的也是訂單最大化。更多的訂單就意味著更多的收入。因此,他們采用異步的方式處理訂單:
點(diǎn)好咖啡后,收銀員會(huì)拿出一個(gè)杯將你的訂單在杯子上做個(gè)標(biāo)記,然后將杯子放到一個(gè)隊(duì)列。這里所說的隊(duì)列其實(shí)就是咖啡機(jī)上的一排杯子;
隊(duì)列將收銀員和咖啡師解耦,使收銀員能夠不斷接單,即使咖啡師已經(jīng)有點(diǎn)忙不過來了。
在這種方式中,如果咖啡師真的忙不過來了,可以再加幾個(gè)咖啡師。這就是所謂的 Competing Consumer 場(chǎng)景。
2 關(guān)聯(lián)
享受異步帶來的好處的同時(shí),星巴克也需要解決異步方式內(nèi)在的挑戰(zhàn)。例如,關(guān)聯(lián)(correlation)問題。
咖啡制作完成的順序不一定與下單的順序一致。這有兩個(gè)可能的原因:
多位咖啡師可能在分別使用不同的咖啡機(jī)同時(shí)制作。另外,不同類型的咖啡所需的 時(shí)間也不同,例如調(diào)配型咖啡會(huì)比已經(jīng)磨好、拿杯子直接接就行的咖啡所花的時(shí)間要長(zhǎng);
咖啡師可能會(huì)將同一咖啡類型的多個(gè)訂單放到同一批制作,以節(jié)省整體的制作時(shí)間。
因此,星巴克會(huì)面臨咖啡與顧客之間的關(guān)聯(lián)問題??Х戎谱魍瓿傻捻樞蚴遣淮_定的,需 要將每一杯咖啡分別對(duì)應(yīng)到正確的顧客。星巴克解決這個(gè)問題的方式與我們?cè)谙⑾到y(tǒng) 中所使用的“模式”是一樣的:使用某種關(guān)聯(lián) ID。
在美國(guó),大部分星巴克都會(huì)將顧客的名字作為顯式關(guān)聯(lián) ID 寫到杯子上,咖啡制作完成后服務(wù)員會(huì)叫顧客的名字;
在其他國(guó)家,可能會(huì)用咖啡的類型來做關(guān)聯(lián)(例如,服務(wù)員會(huì)喊:“大杯摩卡好了”)。
3. 異常處理
異步消息系統(tǒng)中的異常處理是很困難的。如果說現(xiàn)實(shí)世界中已經(jīng)很好的解決了這個(gè)問題,那我們可以通過觀察星巴克如何處理異常學(xué)到一些東西。
如果付款失敗,他們會(huì)怎么做?
如果咖啡已經(jīng)做好了,他們會(huì)倒掉;
如果還沒有開始做,他們會(huì)將杯子從“隊(duì)列”中拿走。
如果咖啡做錯(cuò)了,或者對(duì)咖啡不滿意?他們會(huì)重新做一杯;
如果咖啡機(jī)壞了,做不了咖啡?他們會(huì)退款。
這些場(chǎng)景分別描述了幾種常見的錯(cuò)誤處理策略。
3.1 銷賬
這是所有錯(cuò)誤處理策略中最簡(jiǎn)單的:什么都不用做,或者丟棄已經(jīng)做的所有東西。
聽起來似乎不靠譜,但實(shí)際業(yè)務(wù)中,有時(shí)這種方式是可接受的。如果銷賬帶來的損失很小, 那相比斥巨資實(shí)現(xiàn)一種復(fù)雜的錯(cuò)誤處理機(jī)制,銷賬的方式還是更劃算的。
例如,我曾為多家因特網(wǎng)服務(wù)提供商(ISP)工作,在他們的業(yè)務(wù)中,如果計(jì)費(fèi)發(fā)生錯(cuò)誤,他們就會(huì)選擇銷賬的方式。其導(dǎo)致的結(jié)果是,客戶可能會(huì) 享受了某些服務(wù),但沒有被收費(fèi)。
這種處理方式給他們帶來的營(yíng)業(yè)損失足夠小,因此業(yè)務(wù)能夠保持運(yùn)營(yíng)。另外,公司會(huì)定期地對(duì)賬,主動(dòng)檢測(cè)這些“免費(fèi)”賬戶并將其關(guān)閉。
3.2 重試
當(dāng)一大組操作(例如一次事務(wù))中的某些操作失敗時(shí),我們基本有兩種選擇:
回退已完成的操作;
重試失敗的操作。
如果重試有較大的概率能成功,那就可以考慮重試方式。例如,
如果失敗的原因是違反了業(yè)務(wù)規(guī)則,那重試就不太可能會(huì)成功;
如果失敗的原因是某個(gè)外部系統(tǒng)掛了,那重試就有可能會(huì)成功。
這里有一種特殊的重試:冪等接收器重試(retry with Idempotent Receiver)。在這種場(chǎng)景中,我們可以簡(jiǎn)單地重試所有操 作,因?yàn)榻邮掌鞒晒χ蟊銜?huì)忽略重復(fù)的消息。
3.3 補(bǔ)償
最后一種方式是回退所有已完成的操作, 讓系統(tǒng)回到一致的狀態(tài)。例如,在金融系統(tǒng)中,這些“補(bǔ)償動(dòng)作”能在交易失敗時(shí)對(duì)已扣款進(jìn)行退款處理。
4. 兩階段提交
以上所有策略都與兩階段提交不同。兩階段提交包含前后兩個(gè)步驟:
準(zhǔn)備階段;
執(zhí)行階段。
如果在星巴克中使用兩階段提交,那買一杯咖啡的過程將變?yōu)椋?/span>
準(zhǔn)備階段:前臺(tái)點(diǎn)單,打印小票,然后將現(xiàn)金和小票都放到臺(tái)面上,等待咖啡做好;
執(zhí)行階段:咖啡做好后,現(xiàn)金、小票和咖啡同時(shí)易手,完成交易。
在“事務(wù)”完成之前,收銀員和顧客都不能離開。
顯然,如果使用這種提交方式,星巴克的業(yè)務(wù)量將急劇下降,因?yàn)橄嗤瑫r(shí)間內(nèi)能服務(wù)的 顧客數(shù)量將銳減。
這個(gè)例子也提醒我們,兩階段提交會(huì)讓生活變得加更簡(jiǎn)單(因?yàn)殄e(cuò)誤處理非常簡(jiǎn)單),但它也會(huì)妨礙消息的自由流動(dòng)(以及自由流動(dòng)帶來的可擴(kuò)展性),因?yàn)樗?strong>必須將多個(gè)異步操作封裝成一個(gè)有狀態(tài)事務(wù)。
5. 會(huì)話模式
咖啡店交互的過程其實(shí)也是一個(gè)簡(jiǎn)單但很常見的 Conversation 模式的例子。
雙方(顧客和咖啡店)之間由兩次交互組成:
時(shí)間較短的同步交互:完成下單和支付;
時(shí)間較長(zhǎng)的異步交互:完成咖啡的制作和交付。
這種類型的會(huì)話在電商場(chǎng)景中是非常普遍的。例如,在 Amazon 買東 西時(shí),時(shí)間較短的異步交互過程會(huì)分配訂單號(hào),而所有的后續(xù)步驟(信用卡扣款、打包、配 送)都是異步完成的。這些額外的異步步驟完成后,你會(huì)收到郵件方式(異步)的通 知。如果中間發(fā)生任何差錯(cuò),Amazon 通常會(huì)進(jìn)行:
補(bǔ)償:退款到信用卡;
重試:補(bǔ)發(fā)配送過程中丟失的物品。
可以看到,真實(shí)世界往往都是異步的。我們的日常生活是由許多協(xié)調(diào)但異步的過程組成的,例如讀取和回復(fù)電子郵件,購(gòu)買咖啡等等 。這意味著,異步消息模型通常能很自然地對(duì)這些類型的交互進(jìn)行建模。
此外,這還意味著,經(jīng)常觀察日常生活有助于設(shè)計(jì)出成功的消息系統(tǒng)。
感謝閱讀!
原文鏈接:https://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
?
往期推薦
掃一掃,關(guān)注我
一起學(xué)習(xí),一起進(jìn)步
每周贈(zèng)書,福利不斷
﹀
﹀
﹀
深度內(nèi)容
推薦加入
最近熱門內(nèi)容回顧? ?#技術(shù)人系列

