Web应用服务网络扩展

一、概述

对于一个简单的web应用,可能只需要一台性能一般的服务器就可以搞定。但是随着网络应用的推广,越来越多的用户需要获取到网络服务。

比如你的网站,网上商店,社交网络,你把它放在网上,每天有几百个访问者经过你的网站,请求迅速得到回复,订单被立即处理,一切都在顺利地进行着。但是可怕的事情发生了:你成功了!越来越多的用户涌入,数以千计,数万,每小时,分钟,秒…对于你的生意来说,这是好消息,可对你的基础设施来说是个坏消息,因为现在,它需要扩展。这意味着它需要能够:

  • 同时服务更多的顾客
  • 随时可用
  • 为全球用户服务

这时如何提高web应用的承载量和可靠性,就成了一个问题。这篇文章,简要介绍几种网络应用扩展的方案。

二、理论分析

进行网络应用扩展,有两种思路:

  1. 提升单台服务器的性能,让服务器在相同时间内,处理更多请求。
  2. 提升服务器数量,把用户分配到不同的机器上去处理,提升服务承载量。

这两种方案分别从“垂直”与“水平”两个维度来思考问题,简而言之,垂直意味着在更强大的计算机上运行同一事物,而水平缩放意味着并行运行许多进程。

但是今天,大家都在使用水平扩展,几乎没有人使用垂直扩展。原因很简单:

  • 高性能计算机虽然功能强大,但是十分昂贵。
  • 一台计算机运行速度是有上限的,这就对垂直延伸的距离提出了严格的限制。

三、水平扩展

1.单服务器数据库

Initial Setup

这可能是你的后端最初的样子。运行业务逻辑的单个应用服务器和存储长期数据的数据库。一切看上去都是好的,但一旦遇到高并发请求,这种模式就没法解决问题了。

2.添加反向代理

Reverse Proxy

准备更大规模的体系结构的初始步骤是添加一个“反向代理”。你可以把它想象成旅馆的接待台,所有的客人来到旅馆都要经过接待台。当然,你也可以让客人直接去他们的房间。但通过接待台,就检查是否允许这个客人进入。同时如果一个房间被关闭,你希望有人用友好的声音告诉客人,而不是让他们陷入困境。

上面形象描述的内容正是反向代理所做的。一个网络请求进入后,我们可以检查请求的合法性,并将这个请求按照规则转发给对应的服务器,如果服务器出现问题,这是用户得到的也会是一个友好的提示,而不是一堆错误。

这里解释一下代理和反向代理,从字面上解释,代理就是代替管理。作为用户来说,使用代理来协助用户完成一些任务,简化用户的操作流程。一般代理是针对于用户来说的,而反向代理就是针对于服务器的代理。当一个来自互联网请求需要服务是,反向代理通过路由转发到我们的服务器,所以我们称之为“反向代理”。

这样的代理完成了许多任务:

  • 健康检查确保我们的实际服务器仍然处于运行状态。

  • 路由将请求转发到正确的端点

  • 认证确保用户实际上被允许访问服务器。

  • 防火墙确保用户只能访问我们允许使用的网络的部分

3.引入负载均衡器

Load Balancer

大多数“反向代理”还有一个诀窍:它们也可以充当负载平衡器。负载平衡器是一个简单的概念:想象一下,一百个用户准备在你的在线商店在规定的分钟支付。不幸的是,支付服务器在指定时间 只能处理50个付款请求。这时就需开启两个收费通道,即运行两个支付服务器。

而负载均衡器的任务是在这两个服务器之间分离传入的支付请求。用户一去左,用户两去右,用户三走左等。当用户数量还在继续增长时,这时只需要继续提高运行服务器数量即可。

4.增长数据库

Multiple Database Instances

使用负载平衡器允许我们在许多服务器之间分配负载。但你能发现问题吗?虽然我们可以利用数十、数百甚至数千个服务器来处理我们的请求,但是它们都存储和检索来自同一数据库的数据。当服务数量达到一定程度后,提供服务的瓶颈就不再是服务器,而是数据库了。

难道我们不能用同样的方法对数据库进行水平扩展吗?很不幸,答案是不行的。不能扩展的原因是数据库 的一致性。假设一个用户向账户中充值了100元,这个数据被记录在A数据库中,但下一次这个用户查询账户余额的时候,数据库B提供了数据,记录显示没有充值。不一致的数据就会导致各种各样的问题。那么我们如何在确保一致性的同时增长数据库呢?

这个解决方案有时被称为主/从设置或读副本的写入。也就是把多个数据库按功能分成两个部分。一个数据库专门负责接收数据并存储它,同时将数据更新到其他数据库,而其他数据库专门负责检索存储的数据。这个解决方案的好处是一致性得到保证,因为数据只写入单个数据库,并且数据流向是单方向的。缺点是我们仍然只有一个数据库实例要写入。对于查询需求较多,写入较少的中小型Web项目来说,这是可以的,但是当数据量极大是,那就不行了。

5.微服务

Microservices

到目前为止,我们只处理了一个服务器:处理支付、订单、库存、服务网站、管理用户帐号等等。

这不一定是件坏事——单服务器意味着更低的复杂性,因此我们的开发人员就不会那么头痛了。但是随着规模的增加,事情变得越来越复杂和低效:

  • 我们的服务器的不同部分被使用到不同的范围——对于每个用户登录,可能有几百个页面浏览和服务要处理,但是所有的操作都是由同一个服务器完成的。
  • 我们的开发团队与我们的应用程序一起成长——但是随着越来越多的开发人员在同一个服务器上工作,他们更有可能互相踩脚趾。
  • 当服务器的某个模块想要升级一个新版本时,这时所有的服务都必须停止。同时系统各个部分相互依赖,很可能因为修改A功能,导致其他功能损坏。

这些挑战的解决方案是一个建筑模式:微服务。这个想法很简单——将服务器分解为功能单元,并将它们部署为独立的、互连的迷你服务器。这有许多好处:

  • 每个服务可以单独调整,使我们能够更好地适应需求。
  • 开发团队可以独立工作,各自负责自己的微服务的生命周期(创建、部署、更新等)。
  • 每个微服务可以使用它自己的资源,例如它自己的数据库,进一步减少在4中描述的问题。
6.缓存与内容分发网络

Adding a Content Delivery Network

什么比工作更有效率?根本不用工作!我们的Web应用程序的很大一部分是由静态资产组成的,比如图像、JavaScript和CSS文件、某些产品的预渲染页面等等。而不是重新计算或重新服务这些资产的每一个请求,我们可以使用一个“缓存”-一个小商店,只记得最后的结果,并把它发给所有感兴趣的人,而不打扰底层服务器。

Cache的大哥被称为“Content Delivery Network”或简称CDN。这使得我们能够从一个物理上接近它们的商店向用户提供内容,而不是每次都将数据传送到全球各地。

7.消息队列

Message Queues

你曾经去过游乐园吗?你走到售票柜台买票了吗?不,你可能需要排队等候了。多个售票亭同时出售门票,但似乎从来没有足够的时间为每个人提供服务,因此,队列开始形成。

同样的概念用于大型Web应用程序。服务器队列只做三件事:

  • 它存储原始的、未处理的任务。
  • 它在一个任务上添加了一个虚拟的粘性说明便签,指明需要做什么。

从这里开始,这张便条是由任何其他服务器拿起的,每个服务器都完成了其中一项任务,把它勾掉并把纸币放回堆里,直到我们的待办事项清单完成为止。管理这些便签的系统称为“消息队列”。使用这样的队列有许多优点:

  • 它解耦任务和处理器。有时很多任务需要处理,有时只有少数。有时很多处理器是可用的,有时只是一两个服务器。通过简单地将任务添加到队列而不是直接处理它们,我们确保我们的系统保持响应,同时没有任务丢失。
  • 它允许我们按需进行规模调整,启动更多的处理器来处理任务。比如某一时间,某个服务需求出现激增,导致队列等待任务超过阈值,这时系统会调度更多的服务器启动,来处理这些任务,但是服务器启动需要时间,在这个时间段内,消息队列就可存储待执行的任务,而不是丢失任务。

好的,如果我们遵循上面的所有步骤,我们的系统现在就可以服务相当大的流量了。但是,如果我们想大的话,我们能做什么呢?嗯,还有一些选择余地:

8.用户分区

Sharding Architecture

什么是分区?相信大家都知道大型网游都会有分区吧,比如国服,外服。。。

当一个应用的服务范围已经非常大时,这时就可以考虑分区,来为更多人提供服务。当然这种分割的规则有很多种,它可以基于任何数量的因素,例如位置、使用频率、硬件性能、用户习惯等等。您可以根据您的需要,将服务器、数据库或堆栈的几乎任何方面碎片化。

9.基于路由的负载均衡

DNS Loadbalancing

一个单一的负载均衡器转发的能力有限,即使你开始购买一些强大的负载均衡器,也有一个处理请求的极限。

幸运的是,有一个世界范围的、分散的稳定层。即使在它到达我们的负载平衡器之前,它也可以用来平衡流量。同时它也是完全免费的。这一层是“域名系统”或简称DNS。通过全球域名注册表,实现域名和ip的映射。这个注册表允许我们指定来自不同的IP的请求,进入不同的负载均衡器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值