假如从餐饮店的角度来看架构…

>>2020,微服务装逼指南

麦当劳作为世界快餐业的巨头之一,可以说是风靡全球圈粉无数。小编个人也是麦当劳的忠实粉丝之一。今天的文章主要就是从餐饮店的角度来讲讲的互联网技术架构发展故事。为了方便故事的讲解,我们假定创始人名称为王小二和赵铁柱。


以下故事,纯属虚构,如有雷同,不胜荣幸。


数据源单独存储

王小二和赵铁柱拿到了家里人给的第一笔资金后,计划在村里开启一家快销食品的饮食店,但是却发现缺少了食材供应商。

假如从餐饮店的角度来看架构...

赵铁柱:我认识一个朋友,他那边提供有大量的食物材料,他叫MySQL

于是乎王小二就和赵铁柱一起去寻找MySQL厂商一起签订食材提供合作协议,食材供应不足的问题暂时告一段落了。

这就叫MySQL数据源存储。

假如从餐饮店的角度来看架构...

这属于最原始的单机版架构,通常将业务服务器和数据库服务器进行分离开来,在对于请求量较小的业务场景时可以这么进行架构设计。比较经典的搭配就是将所有的核心代码都封装在一个mvc模块中,用些常见的ssh,ssm,springboot等框架技术进行封装,然后数据库部分使用MySQL。


前后端分离

随着王小二和赵铁柱的不断努力,饮食店光顾的客人越来越多,发现光靠两个人根本忙不过来,两个人而且既要做招待客人,又要烹饪食材,质量很难保证。

假如从餐饮店的角度来看架构...

王小二:我发现我们没有规划好分工,经常会忙到一起去,职责很乱,效率很低下。

赵铁柱:是的,所以我有个想法。我口才好,我来招待客人,你的厨艺厉害,负责后台的食物烹饪如何?这样子的话我们前后台分离,职责划分一致,更加能发挥各自的长处。

王小二:有道理,那我们就这样试试吧。

就这样在接下来的一周里面,王小二和赵铁柱分工变得明确了起来,工作起来不亦乐乎。

这就叫前后端分离

假如从餐饮店的角度来看架构...

前后端分离的主要目的是将前端开发人员的职务和后端开发人员的职务进行明确划分,同时也有利于代码进行解耦和维护,拓展性也会加强许多,通常选择这种架构进行开发的技术方案需要有前端开发人员和后端开发人员,常用的技术框架搭配可以是vue,react...结合 ssh,ssm,springboot系列进行搭配。但是这样的搭配仍然是有很大的性能局限性


负载均衡

渐渐的,两人发现客人来的越来越多,光靠一个人烹饪的话,效率实在是赶不上。于是乎二人又开始琢磨对策了。

假如从餐饮店的角度来看架构...

王小二:现在光靠我一个人来处理客人每天的订单实在是太累了,需要找多几个人来帮忙才行。

赵铁柱:ok,我帮你找下。(打开了手机,联系了好几个以前认识的朋友....)

到了下午,来了好几个帮忙的新人,分别是Nginx,Tomcat1,Tomcat2,Tomcat3,然后进行了逐一的自我介绍。

假如从餐饮店的角度来看架构...

Nginx:你好,我是来出生于俄罗斯那边的Nginx,来自隔壁C语言村,我们对于客户的需求处理效率极高,可以快速做出反馈通知给后台这边。所以我觉得我可以胜任这边的店小二一职位。

Tomcat1,Tomcat2,Tomcat3:我们是来自对面JAVA村的人,处理前台的信息一直都以稳定,高效著称,相信我们的加入会帮你减轻很多负担。

于是大家一起商量好了对策,Nginx负责接收客人的点菜请求信息,然后通过一个上菜窗口来传递信息给后台,然后后台进行食物的准备。

那么Nginx是如何将订单消息传输给后台的呢?现在有三个(Tomcat)厨师,每次下单之后应该通知哪位厨师做菜呢?王小二灵机一动,指定了几条策略:

  • 轮询访问:按照Tomcat1-->Tomcat2-->Tomcat3的顺序轮流访问,通知不同的厨师来做菜。

  • 随机访问:每次有客人下单,Nginx都通过抽签的形式来进行随机指明厨师做菜。

  • 最少链接法:谁的需求单最少,就指令相应的厨师做菜。

  • 响应最快法:哪位厨师的做菜效率高,就选择哪位厨师。

  • 哈希法:下单的顾客如果是小孩,就交给Tomcat1,如果是年轻人,就交给Tomcat2,如果是中年人或者老人,就交给Tomcat3。

这就是前后端分离+负载均衡

假如从餐饮店的角度来看架构...

当随着客户请求的次数增加,通常我们会采用这种模式的架构进行搭建项目,将前端页面放置在nginx服务器上边进行加载,然后通过在nginx里面进行upstream的配置定制相应的负载均衡策略,在后端业务模块通过使用Tomcat来进行横向扩展,提高性能的承载能力。


MySQL的主从架构

王小二和赵铁柱两个人因为请了员工的帮忙,现在已经开始过上了小老板的生活了。但是渐渐的,随着的客人光顾的次数不断增加,又遇到了一个新的难题:MySQL那边的供应量开始出现供不应求的情况了,终于有一天,MySQL那边的生产机器坏了,导致该日一整天的生意都中断了。

假如从餐饮店的角度来看架构...

MySQL:你们店铺现在的生意实在是太火爆了,光靠我一个厂在做食材输出,压力实在是太大了。我认识个我的同乡兄弟slave,我把他叫来一起帮忙生产吧。

王小二:那如果你这边再次出现生产中断,你的那个兄弟会怎么处理啊

MySQL:放心,如果后边我的生产在遇到了问题,slave会立马跑来顶替我的任务,这样就能解决之前压力中断导致的问题了。

王小二:有道理,那就这样安排吧。



这就叫做MySQL的主从架构

假如从餐饮店的角度来看架构...

随着系统应用访问量逐渐增大,单台数据库读写访问压力也随之增大,当读写访问达到一定瓶颈时, 将数据库的读写效率骤然下降,甚至不可用。为了解决此类问题,通常会采用mysql集群,当主库宕机后,集群会自动将一个从库升级为主库,继续对外提供服务Master主机将数据操作记录在指定的日志文件里面,然后Slave主机之间通过IO线程来读取日志内容,同步操作到本机上去。一旦出现了故障,通过配置的keepalived信息可以自动实现主从的切换。



分库分表

突然有一天,有个大客户光顾了餐饮店,一次定下了一大笔的订单,导致MySQL 厂生产食材的压力趋于极限。王小二和赵铁柱看到MySQL厂商连夜生产食物已经喘不过气了,于是某天晚上,大伙们又一起坐下来进行商量了。

假如从餐饮店的角度来看架构...

MySQL这次这笔订单的数目实在是太大了,光靠我们两厂根本忙不过来。需要叫上我的另一个兄弟MyCat和其余MySQL厂来帮忙才行。

于是生产方的策略进行了改变,由MyCat作为接单队长,然后下令给多个(MySQL)厂商,然后每个(MySQL)厂商也叫上自己的(salve)小弟进行协助,熬了好几个通宵,很快,这笔大订单就搞定了。

这就叫做基于MyCat中间件的分库分表方案

假如从餐饮店的角度来看架构...

使用MyCAT这种中间件最主要的核心功能点就是分库分表,将一个大表水平划分为了N个小表。MyCAT的原理可以用“拦截”一词来形容,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析,如分片分析,路由分析,读写分离分析,缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当处理,最终返回给用户。


微服务架构

由于之前接下了一大笔订单,店铺的经济一下子好了许多。于是王小二和赵铁柱开始扩大了店铺的面积,请了更加多的Tomcat厨师来干活。但是渐渐地又遇到了新的问题。

假如从餐饮店的角度来看架构...

王小二:你有没有发现这些订单有一定的规律啊,就是通常薯条的下单量比汉堡的需求量要大,雪糕甜筒类的需求量比汽水饮料的需求量要高。Tomcat1他炸的薯条特别好吃,适合分配去负责薯条领域。Tomcat2做汉堡的能力很出众,适合分配去负责汉堡区域。Tomcat3做甜点和冷饮的能力很厉害,适合去负责这些部分。

赵铁柱:嗯嗯,我觉得你说的很有道理,那就让他们分别带些小弟,负责不同的食物模块吧。等等,那一个模块里面有多个厨师干活,那该怎么进行模块内的任务分配呢?

王小二:你之前不是给每个模块都指定了一个负责人嘛,例如薯条部分就由负责人扮演消费者一角色,其余厨师扮演服务提供者一角色。负责人则采用你之前制定的策略(负载均衡策略)来进行指派任务即可。所有的厨师都必须在Zookeeper员工报道系统上进行报道,这样我们可以统一查看工作详细信息。

于是没过几天,后台那边的厨师分配结构又发生了一次组织调整。经过几周的演练,两位老板发现生产效率大大提升。

这就叫做微服务架构

假如从餐饮店的角度来看架构...

“微服务架构”一词大概也是近些年来才出现,它将整体的业务模块拆分成了多个小而独立的子模块,然后每个子模块之间都会进行基于不同协议的相应通信。互联网公司里面经常会有微服务技术的身影,比较著名的微服务框架有Dubbo,SpringCloud


消息中间件

随着厨房的模块划分仔细之后,渐渐的两位老板又发现了相应的问题情况了。炸薯条的厨师想要和负责汉堡模块的厨师进行沟通的话需要通过隔空喊话的形式来进行信息交流。由于厨房的环境嘈杂,经常会出现传输无效或是无法确认是否传输到位的情况

假如从餐饮店的角度来看架构...

于是机智的王小二找到了厨师们进行讨论,然后有人提出建议去找隔壁村的朋友RocetMQ进行帮忙。后来RocetMQ加入了饮食店工作,主要负责帮各个厨师之间的进行消息的传递,大大提升了各个厨房模块之间工作的效率。

这个叫做消息中间件传输数据

假如从餐饮店的角度来看架构...

MQ消息队列主要是在各个微服务模块之间进行相应的数据中转,能够起到系统解耦,削峰等作用,因此这种技术成为了微服务架构中非常受欢迎的技术中间件。常见的MQ消息队列中间件有RabbitMQ,ActiveMQRocketMQ,Kafka。


缓存设计

由于雪糕等冷饮的需求量急剧上升,店铺经常需要去找食材厂商那边领取相应食材原料,然后运输过来店铺这边,运输的形式太慢了加上店铺本身能存储食材的室内空间有限,王小二和赵铁柱又要开始头疼了,这时候nginx和他们提了个建议。

假如从餐饮店的角度来看架构...

nginx我们每次从厂房那边运输食材过来,但是店铺的室内仓库太小了,一次能保存的食材也是有限,不妨试试在店铺后院搭建一个临时仓库,增加我们的食材存储能力?

王小二:你有什么好的人选和方案吗?

nginx:我认识一个叫做Redis的朋友,他能帮上忙。

第二天Redis就过来了,然后在店铺的周边设置了几个临时仓库点,进行食材的临时存储,这样就可以保证不需要每次都去厂商那边拿食材了,提高了厨师们的工作效率。Redis为了保证仓库存储的食材能尽可能的足够,因此搭建了多个仓库临时点,由于每个仓库都有自己独立的发电机,为了防止某间仓库的发电机崩溃之后食材不能得以保鲜,因此每间仓库都有相应的备用子仓库。

这就是分布式Redis缓存分片架构

假如从餐饮店的角度来看架构...

上图中的redis图标描述的redis cluster方案架构,通过对数据进行哈希计算之后放在不同的槽点,然后每个槽点都设置主从模式增强其容错性,采用分片模式的缓存架构可以增加系统的缓存数据量。


或许理想的微服务架构是比较清晰明确的,各个模块负责各个模块的内容,但往往现实中却很难做到完美无暇。

理想 vs 现实

假如从餐饮店的角度来看架构...


王小二和赵铁柱开店铺的模式纯属虚构,如有雷同,不胜荣幸......



假如从餐饮店的角度来看架构...



推荐阅读(点击即可跳转阅读)


1. SpringBoot内容聚合

2. 面试题内容聚合

3. 设计模式内容聚合

4. Mybatis内容聚合

5. 多线程内容聚合

假如从餐饮店的角度来看架构...

原文始发于微信公众号(后端技术精选):假如从餐饮店的角度来看架构...