Categories
程式開發

像經營咖啡店一樣擴容Web系統



{“ type”:“ doc”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:” “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”第一篇文章,弄点轻松点的。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”这是一篇”},{“type”:”text”,”marks”:[{“type”:”color”,”attrs”:{“color”:”#F5222D”,”name”:”red”}}],“ text”:“譯文”},{“ type”:“ text”,“ text”:“,文章使用一個經營咖啡店的示例示例解法Web應用擴展容會經歷的幾個階段,很有意思,通俗易懂。“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”原文地址:”},{“type”:”link”,”attrs”:{“href”:”http://highscalability.com/blog/2014/3/17/intuitively-showing-how-to-scale-a-web-application-using-a-c.html”,”title”:””},”content”:[{“type”:”text”,”text”:”http://highscalability.com/blog/2014/3/17/intuitively-showing-how-to-scale-a-web-application-using-a-c.html”}]}]},{“ type”:“ horizo​​ntalrule”},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null} },{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”我有一个小咖啡店。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”店铺的开销和资源成正比: “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”100平方英尺的店铺面积和公用设施,一个服务员,一台咖啡机。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”店铺的容量: “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”同一时间只能服务一个顾客,花 3 分钟出咖啡,服务完一个顾客总共会花 5 分钟。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”假设服务员从来不休息,而且这台德国造的咖啡机不出问题,这个咖啡店的最大吞吐量是:12 个顾客 / 小时。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image” ,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/2a/2a27bc9296ded011387b75947cabc2c9.png”,“ alt”:null,“ title”:“”,“ style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”Web 服务器 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”同一时间只能服务一个客户,所以顾客会在高峰时期离开,这里也没有地方让人等。 我把店铺升级了,新店铺看起更好。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在的开销: “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”同样的店铺面积,3 个服务员,2 个咖啡制造机,2 把椅子。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在店铺的容量: “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”3 分钟可以出 2 杯咖啡,7 分钟内可以服务 3 个顾客,还可以让 2 个顾客坐在椅子上排队等候。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”店铺的并发顾客数 = 3 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”店铺的顾客容量 = 5 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image”,“ attrs”:{“ src”: “ https://static001.geekbang.org/infoq/6d/6daf513d4731390a163112b6d4ff1063.png”,”alt”:null,”title”:””,”style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”垂直扩容 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”业务正在爆炸式增长,又该升级了,更大点会更好。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”现在的开销: “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”200 平方英尺的区域,5 个服务员,4 台咖啡机,3 把椅子。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”店铺的容量在线性增长,情况很好。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”但是到夏天时,客流量下降了,这对于咖啡店来说很正常,所以我又想把店铺的规模缩小,但是我的房东却不允许我那么做。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”垂直扩容对我这个客流量不稳定的店来说太贵了,大规模不一定好。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image”,“ attrs”:{“ src”: “ https://static001.geekbang.org/infoq/56/5614a638c57130e45390203bc4530a87.png”,”alt”:null,”title”:””,”style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”通过负载均衡器来水平扩容 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”房东愿意按照固定的区域(容纳 3 个服务员)来扩大或者缩小,如果我提前告知的话,他可以很轻松的打开或者关闭一个摊位。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”如果我可以通过一个店面来同时管理多个摊位。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”还真有这么一种柜台(”},{“type”:”text”,”marks”:[{“type”:”strong”}],“ text”:“負載均衡器”},{“ type”:“ text”,“ text”:“)就是專門用來應對這種情況的。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”它允许多个顾客同时与一个服务员交谈,实际上面对顾客的这个雇员不需要去制作咖啡了,只需要与顾客交谈并且将订单分发给制作咖啡的人。并且制作咖啡的人也不用来面对这些讨厌的顾客了。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”这样做的优点是:如果我需要扩大规模,我可以直接添加一个可以容纳三个服务员的区域(和房东达成的协议),然后把这个区域和柜台连接起来,反之也可以用这种方式来缩小规模。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”虽然费用增加了,但我也能更好地处理店铺的容量。我可以进行水平的扩容和缩容。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image”,“ attrs”:{“ src”: “ https://static001.geekbang.org/infoq/44/448c31b0d1e06e6aa506fab30f6a4a48.png”,”alt”:null,”title”:””,”style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”资源集中处理 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”我的咖啡机还可以用来处理制作食物,许多顾客告诉我他们想要买新鲜的烘焙面包,我就这个添加到菜单了。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”但是有一个问题,一次能制作 2 杯咖啡的机器只能制作 1 磅面包,而且还要花两倍的时间。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”在单位时间内, “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”生产 1 磅面包 = 制作 4 杯咖啡 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”有时候面包订单已经阻塞我的系统了,点咖啡的人也在不满的等待着,关于我工作低效的言论已经开始扩散开了。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”我需要利用现有的资源来优化订单的处理方式。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:” “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image” ,“ attrs”:{“ src”:“ https://static001.geekbang.org/infoq/47/47d2eac3b489f838c4b3063c3cbef30b.png”,“ alt”:null,“ title”:“”,“ style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”基于异步队列的处理方式 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”我引入了一个基于令牌的队列系统。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”顾客进入到店之后,提交订单,然后拿一个令牌号码在等待。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”这个订单按照类型进入不同的队列:面包或是咖啡。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”服务员通过队列来决定他们接下来是烘焙面包还是制作咖啡。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”当一份面包或者一杯咖啡就绪之后,就会被放到一个输出托盘上,处理订单的服务原就会喊出令牌号码,顾客就可以取走面包或咖啡。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ bulletedlist” ,“內容”:[{“type”:”listitem”,”content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”输入队列和输出托盘是新加入的,其他的资源都是现成的,只不过在用不同的方式在工作 “}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”从顾客的视角来说,现在是完全不同的了 “}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”店铺开销和容量的计算已经很复杂了,整个系统的复杂度也在上升,如果出现问题,就很难进行排查和修复问题 “}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”如果顾客接受了这种异步系统,那我们就可以管理这种复杂性了,它提供了一种方式来扩打容量和生产不同种类的产品,我可以用这种方式来吓一吓我们对面的竞争者了 “}]}]}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ image”,“ attrs”:{“ src”: “ https://static001.geekbang.org/infoq/40/40753e74427ebaf607e13130468a72d6.png”,”alt”:null,”title”:””,”style”:[{“key”:”width”,”value”:”75%”},{“key”:”bordertype”,”value”:”none”}],“ href”:“”,“ fromPaste”:false,“ pastePass”:false}},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align “:null,” origin“:null}},{” type“:” heading“,” attrs“:{” align“:null,” level“:2},” content“:[{“type”:”text”,”text”:”后续 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”我们已经达到了 Web 服务器的极限了,负载均衡,异步队列系统都用上。然后还可以做什么? “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”在后续阶段,用咖啡店来做比喻已经完全站不住脚了。如果你想了解更多,可以去搜索 DNS 负载和其他的扩容技术。如果你是 Web 应用扩容的新手,使用这篇文章中提到的技术就够了。咖啡店运营是一个经过简化的例子,以便激发读者对 Web 应用扩容的兴趣。如果你想深入学习,可以修改这个系统,然后与专业的人进行深入的讨论。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”marks”:[{“type”:”color”,”attrs”:{“color”:”#F5222D”,”name”:”red”}}],“ text”:“譯/ Rayjun”}]}]}