星巴克是如何处理订单的?
点击上方蓝色“程序猿DD”,选择“设为星标”
回复“资源”获取独家整理的学习资料!
来源:r6d.cn/6dyh
译者序
本文翻译自 2004 年的一篇文章: Starbucks Does Not Use Two-Phase Commit.
1. 请给我一杯热巧克力(Hotto Cocoa o Kudasai)
刚结束了一次为期两周的日本之旅。印象深刻的是数量多到难以置信的星巴克 —— 尤其是在 新宿和六本木地区。在等待咖啡制作时,我开始思考星巴克是如何处理订单的。
与大多数商业公司一样,星巴克主要关心的也是订单最大化。更多的订单就意味着更多的收入。因此,他们采用异步的方式处理订单:
点好咖啡后,收银员会拿出一个杯将你的订单在杯子上做个标记,然后将杯子放到一个队列。这里所说的队列其实就是咖啡机上的一排杯子;
队列将收银员和咖啡师解耦,使收银员能够不断接单,即使咖啡师已经有点忙不过来了。
在这种方式中,如果咖啡师真的忙不过来了,可以再加几个咖啡师。这就是所谓的 Competing Consumer 场景。
2 关联
享受异步带来的好处的同时,星巴克也需要解决异步方式内在的挑战。例如,关联(correlation)问题。
咖啡制作完成的顺序不一定与下单的顺序一致。这有两个可能的原因:
多位咖啡师可能在分别使用不同的咖啡机同时制作。另外,不同类型的咖啡所需的 时间也不同,例如调配型咖啡会比已经磨好、拿杯子直接接就行的咖啡所花的时间要长;
咖啡师可能会将同一咖啡类型的多个订单放到同一批制作,以节省整体的制作时间。
因此,星巴克会面临咖啡与顾客之间的关联问题。咖啡制作完成的顺序是不确定的,需 要将每一杯咖啡分别对应到正确的顾客。星巴克解决这个问题的方式与我们在消息系统 中所使用的“模式”是一样的:使用某种关联 ID。
在美国,大部分星巴克都会将顾客的名字作为显式关联 ID 写到杯子上,咖啡制作完成后服务员会叫顾客的名字;
在其他国家,可能会用咖啡的类型来做关联(例如,服务员会喊:“大杯摩卡好了”)。
3. 异常处理
异步消息系统中的异常处理是很困难的。如果说现实世界中已经很好的解决了这个问题,那我们可以通过观察星巴克如何处理异常学到一些东西。
如果付款失败,他们会怎么做?
如果咖啡已经做好了,他们会倒掉;
如果还没有开始做,他们会将杯子从“队列”中拿走。
如果咖啡做错了,或者对咖啡不满意?他们会重新做一杯;
如果咖啡机坏了,做不了咖啡?他们会退款。
这些场景分别描述了几种常见的错误处理策略。
3.1 销账
这是所有错误处理策略中最简单的:什么都不用做,或者丢弃已经做的所有东西。
听起来似乎不靠谱,但实际业务中,有时这种方式是可接受的。如果销账带来的损失很小, 那相比斥巨资实现一种复杂的错误处理机制,销账的方式还是更划算的。
例如,我曾为多家因特网服务提供商(ISP)工作,在他们的业务中,如果计费发生错误,他们就会选择销账的方式。其导致的结果是,客户可能会 享受了某些服务,但没有被收费。
这种处理方式给他们带来的营业损失足够小,因此业务能够保持运营。另外,公司会定期地对账,主动检测这些“免费”账户并将其关闭。
3.2 重试
当一大组操作(例如一次事务)中的某些操作失败时,我们基本有两种选择:
回退已完成的操作;
重试失败的操作。
如果重试有较大的概率能成功,那就可以考虑重试方式。例如,
如果失败的原因是违反了业务规则,那重试就不太可能会成功;
如果失败的原因是某个外部系统挂了,那重试就有可能会成功。
这里有一种特殊的重试:幂等接收器重试(retry with Idempotent Receiver)。在这种场景中,我们可以简单地重试所有操 作,因为接收器成功之后便会忽略重复的消息。
3.3 补偿
最后一种方式是回退所有已完成的操作, 让系统回到一致的状态。例如,在金融系统中,这些“补偿动作”能在交易失败时对已扣款进行退款处理。
4. 两阶段提交
以上所有策略都与两阶段提交不同。两阶段提交包含前后两个步骤:
准备阶段;
执行阶段。
如果在星巴克中使用两阶段提交,那买一杯咖啡的过程将变为:
准备阶段:前台点单,打印小票,然后将现金和小票都放到台面上,等待咖啡做好;
执行阶段:咖啡做好后,现金、小票和咖啡同时易手,完成交易。
在“事务”完成之前,收银员和顾客都不能离开。
显然,如果使用这种提交方式,星巴克的业务量将急剧下降,因为相同时间内能服务的 顾客数量将锐减。
这个例子也提醒我们,两阶段提交会让生活变得加更简单(因为错误处理非常简单),但它也会妨碍消息的自由流动(以及自由流动带来的可扩展性),因为它必须将多个异步操作封装成一个有状态事务。
5. 会话模式
咖啡店交互的过程其实也是一个简单但很常见的 Conversation 模式的例子。
双方(顾客和咖啡店)之间由两次交互组成:
时间较短的同步交互:完成下单和支付;
时间较长的异步交互:完成咖啡的制作和交付。
这种类型的会话在电商场景中是非常普遍的。例如,在 Amazon 买东 西时,时间较短的异步交互过程会分配订单号,而所有的后续步骤(信用卡扣款、打包、配 送)都是异步完成的。这些额外的异步步骤完成后,你会收到邮件方式(异步)的通 知。如果中间发生任何差错,Amazon 通常会进行:
补偿:退款到信用卡;
重试:补发配送过程中丢失的物品。
可以看到,真实世界往往都是异步的。我们的日常生活是由许多协调但异步的过程组成的,例如读取和回复电子邮件,购买咖啡等等 。这意味着,异步消息模型通常能很自然地对这些类型的交互进行建模。
此外,这还意味着,经常观察日常生活有助于设计出成功的消息系统。
感谢阅读!
原文链接:https://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
往期推荐
MIT黑科技:通过手机记录的咳嗽数据检测是否感染新冠病毒
为什么我使用了索引,查询还是慢?
10个你可能不曾用过却很有用的 LINUX 命令
分享一个Java开发都用得到的密码摘要算法包
程序员编码时都戴耳机?到底在听什么?
Spring Data 发布更改版本管理方案之后的第一个版本:2020.0.0
扫一扫,关注我
一起学习,一起进步
每周赠书,福利不断
﹀
﹀
﹀
深度内容
推荐加入
最近热门内容回顾 #技术人系列
星巴克是如何处理订单的?相关推荐
- 星巴克不使用两阶段提交
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:r6d.cn/6dyh 译者序 本文翻译自 2004 ...
- 星巴克REST案例分析(转载自InfoQ)
作者 Jim Webber, Savas Parastatidis & Ian Robinson译者 徐涵 发布于 2008年12月3日 下午7时28分 社区 SOA 主题 工作流/业务流程管 ...
- 如何获取(GET)一杯咖啡——星巴克REST案例分析
我们已习惯于在大型中间件平台(比如那些实现CORBA.Web服务协议栈和J2EE的平台)之上构建分布式系统了.在这篇文章里,我们将采取另一种做法:我们把支撑Web运行的协议和文档格式视为一种应用平台, ...
- 如何获取(GET)一杯咖啡——星巴克REST案例分析【转】
原文:http://www.infoq.com/cn/articles/webber-rest-workflow 我们已习惯于在大型中间件平台(比如那些实现CORBA.Web服务协议栈和J2EE的平台 ...
- 如何获取(GET)一杯咖啡——星巴克REST案例分析(转)
如何获取(GET)一杯咖啡--星巴克REST案例分析 来源:http://www.infoq.com/cn/articles/webber-rest-workflow 作者 Jim Webber, S ...
- 星巴克和阿里“结婚”,这后面真的不简单
星巴克与阿里巴巴为什么会"结婚"? 8月2日,上海,星巴克与阿里巴巴集团在宣布达成新零售全面战略合作.用星巴克CEO凯文·约翰逊(Kevin Johnson)的话来说,世界领先的高 ...
- 互联网晚报 | 2月17日 星期四 | 小鹏汽车回应总裁年薪超4亿;B站将上线开播前人脸认证功能;星巴克再次涨价...
今日看点 ✦ Redmi K50电竞版正式发布:搭载高通骁龙8Gen1,售价3299元起 ✦ 小鹏汽车回应"总裁年薪超4亿":系误解,实为多年累积的股权激励 ✦ B站直播新规:开播 ...
- 瑞幸“踩”着星巴克登顶?
来源 | 运营研究社 ID | U_quan 作者 |于丽言 郑宇轩 编辑 |杨佩汶 设计 |王浩南 3 月 24 日晚,瑞幸咖啡发布 2021 年 Q4 及全年财报,数据表现亮眼,较去年的净收入近乎 ...
- 留给星巴克的时间不多了
出品|虎嗅商业.消费与动机组 ID|huxi_com 作者|苗正卿 "傲慢"的星巴克道歉了. 2月14日晚,星巴克中国通过官方微博公开道歉,针对2月13日引起舆论关注的星巴克门店& ...
最新文章
- Error in hist.default(data) : ‘x‘ must be numeric
- 面部特征点检测的关键技术
- CTFshow 命令执行 web65
- 成功解决ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or
- LeetCode 25 K个一组翻转链表
- python全免费教程-python教程免费
- adb shell 小米手机_【ADB命令实战】免ROOT停用小米手机系统应用
- python教程五(imput和while)
- 超级牛人华为工作十年离职感想
- 《Unity 2018 AR与VR开发快速上手》简介
- 基于STM32F103平台的ADS79xx系列ADC(TI公司)应用方案
- 2018刚入手一台UGP U8VR眼镜,ugp vr眼镜怎么样评测效果好不好,跟我看看
- Docker报错Error spawning command line “dbus-launch --autolaunch=xxx --binary-syntax --close-stderr”
- Python基础学习_函数数def_返回值及返回值类型_函数块
- 计算机视觉检测 白皓月,基于视线跟踪的操作界面的人机交互方法研究
- 通往强人工智能,少不了的模拟大脑
- LeetCode第172场周赛:5322. 工作计划的最低难度(动态规划)
- 五、Scikit-learn的应用-为CHarityML寻找捐献者
- MySQL 学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher)
- 流量思维:拉新、留存、转化、裂变-运营设计(0)
热门文章
- MSN8.0?!O My God,it's so perfect!
- python加载shellcode免杀 简介
- python 排序 自定义函数
- golang go get 命令行安装库 报错 go: cannot use path@version syntax in GOPATH mode 解决方法
- 分析和解密已加密的路由器固件
- python3 redis操作 错误 cannot import name 'StrictRedis' from 'redis'
- golang 开发常见坑
- linux 内核 struct file_operations中 ioctl 变为 unlocked_ioctl
- 变量命名规范 匈牙利 下划线 骆驼 帕斯卡
- nsswitch.conf文件详解