图解:从单个服务器扩展到百万用户的系统
作者:CQITer小编 时间:2019-04-04 21:01

你开发了一个网站(例如网上商店、社交网站或者其他任何东西),之后你把它发布到了网上,网站运行良好,每天有几百的访问量,能快速地相响应用户的请求。
但是有一天,不知道什么原因,你的网站出名了!
每分每秒都有成千上万的用户蜂拥而至,你的网站变得越来越慢……
对你来讲,这是个好消息,但是对你的Web应用来说这是个坏消息。因为现在它需要扩展了,你的应用需要为全球用户提供7*24不宕机服务。
如何进行扩展?
几年前,我讨论过水平扩展与垂直扩展。简而言之, 垂直扩展意味着在性能更强的计算机上运行同样的服务,而水平扩展是并行地运行多个服务。
如今,几乎没有人说垂直扩展了。原因很简单:
随着计算机性能的增长,其价格会成倍增长
单台计算机的性能是有上限的,不可能无限制地垂直扩展
多核CPU意味着即使是单台计算机也可以并行的。那么,为什么不一开始就并行化呢?
现在我们水平扩展服务。需要哪些步骤呢?
1.单台服务器 + 数据库

上图可能是你后端服务最初的样子。有一个执行业务逻辑的应用服务器(Application Server)和保存数据的数据库。
看上去很不错。但是这样的配置,满足更高要求的唯一方法是在性能更强的计算机上运行,这点不是很好。
2. 增加一个反向代理

成为大规模服务架构的第一步是添加反向代理。类似于酒店大堂的接待处。
你也可以让客人直接去他们的客房。但是实际上,你需要一个中间人他去检查是否允许客人进入, 如果客房没有开放,得有人告诉客人,而不是让客人处于尴尬的境地。这些事情正是反向代理需要做的。
通常,代理是一个接收和转发请求的过程。正常情况下,「正向代理」代理的对象是客户端,「反向代理」代理的对象是服务端,它完成这些功能:
健康检查功能,确保我们的服务器是一直处于运行状态的
路由转发功能,把请求转发到正确的服务路径上
认证功能,确保用户有权限访问后端服务器
防火墙功能,确保用户只能访问允许使用的网络部分等等
3.引入负载均衡器

大多数反向代理还有另外一个功能:他们也可以充当负载均衡器。
负载均衡器是个简单概念,想象下有一百个用户在一分钟之内在你的网店里付款。遗憾的是,你的付款服务器在一分钟内只能处理50笔付款。这怎么办呢?同时运行两个付款服务器就行了。
负载均衡器的功能就是把付款请求分发到两台付款服务器上。用户1往左,用户2往右,用户3再往左。。。以此类推。
如果一次有500个用户需要立刻付款,这该怎么解决呢?确切地说,你可以扩展到十台付款服务器,之后让负载均衡器分发请求到这十台服务器上。
4.扩展数据库

负载均衡器的使用使得我们可以在多个服务器之间分配负载。但是你发现问题了吗?尽管我们可以用成百上千台服务器处理请求,但是他们都是用同一个数据库存储和检索数据。
那么,我们不能以同样的方式来扩展数据库吗?很遗憾,这里有个一致性的问题。
系统使用的所有服务需要就他们使用的数据达成一致。数据不一致会导致各种问题,如订单被多次处理,从一个余额只有100元的账户中扣除两笔90元的付款等等......那么我们在扩展数据库的时候如何确保一致性呢?
我们需要做的第一件事是把数据库分成多个部分。一部分专门负责接收并存储数据,其他部分负责检索数据。这个方案有时称为主从模式或者单实例写多副本读。这里假设是从数据库读的频率高于写的频率。这个方案的好处是保证了一致性,因为数据只能被单实例写入,之后把写入数据同步到其他部分即可。缺点是我们仍然只有一个写数据库实例。
这对于中小型的Web应用来说没问题, 但是像Facebook这样的则不会这样做了。我们会在第九节中研究扩展数据库的步骤。
5.微服务

到目前为止,我们的付款、订单、库存、用户管理等等这些功能都在一台服务器上。
这也不是坏事,单个服务器同时意味着更低的复杂性。随着规模的增加,事情会变得复杂和低效:
开发团队随着应用的发展而增长。但是随着越来越多的开发人员工作在同一台服务器上,发生冲突的可能性很大。


