“快速”是什么意思?

作者:Reuven Lerner

好消息!我的一位客户正在发起一项新的营销活动,我们预计这将使业务比以往任何时候都更加成功。

坏消息!这意味着我们的 Web 应用程序,它已经在相当简单的基础设施上存在了一段时间,并且已经处理了稳步增长的用户数量,现在(我们希望)需要处理用户数量的激增。

最大的问题是:我们的服务器能否处理我们预期的负载?实际上,我们能预期什么样的负载?而且,如果我们需要进一步提高容量会发生什么?

因此,在本文中,我将介绍一些与 Web 可扩展性相关的基本要点,描述一些需要牢记的关键事项。下个月,我将更深入地探讨这些想法,并讨论一些您可以用来提高应用程序速度或表面速度的技术。

背景

我的许多客户都是需要 Web 应用程序的公司,但不熟悉 Web 的工作方式。他们经常问我的一个问题是:“我们每个月有成千上万的用户。服务器能处理这么多人吗?”当我解释说,用户只有在主动发出 HTTP 请求时才会消耗服务器资源时,他们的理解开始提高。一家每月有 10,000 名访客的公司无需担心 10,000 名同时访客;他们很可能在某些时间段内只有几十个访客,而在其他时间段内则完全没有访客。因此,扩展他们的基础设施以处理 10,000 名同时用户将是愚蠢的。

与此同时,在某些时候——例如在发起广告宣传活动或在电视节目中被提及之后——您确实会遇到流量的巨大激增。在超级碗期间投放广告的公司不仅期望获得数百万观众,还期望其中许多人在观看广告后(或期间)访问他们的网站。这意味着正常的扩展假设不再适用。

这就是亚马逊 EC2 如此受欢迎的原因之一。如果您可以将服务器视为一种商品,按小时付费并根据需要启动和关闭服务器,您就可以解决这个扩展问题。随着流量的增加,您添加更多服务器。随着流量的减少,您移除它们。

但当然,生活比这复杂得多。首先,每个系统都有瓶颈,不能仅仅通过自动扩展来消除。例如,如果事实证明您的数据库无法处理大量负载,并且您只有一个数据库服务器,那么自动扩展您的 Web 服务器可能会加剧问题,而不是解决问题。

其次,尽管想象自动扩展服务器的无限预算很美好,但更现实的想法可能不仅是增加服务器的数量,还要提高每台服务器的效率。如果有一些方法可以提高代码的效率,那么在投入(虚拟)硬件解决问题之前,这通常是扩展工作的一个好地方。

第三,如果您负责网站的技术基础设施,那么您对“我们可以同时为多少人提供服务”这个问题的回答可能不应该是“它是无限的,假设预算无限”。技术人员可能会喜欢这个答案,但公司的首席财务官可能会对给 IT 部门开一张空白支票有点意见。

什么是速度?

许多非技术人员会说“我想要一个快速的网站。” 然而,从技术角度来看,这不是一个非常有用的陈述,因为它既没有区分不同类型的速度,也没有考虑现代 Web 应用程序中涉及的多个层,也没有考虑到多个人以及站点突然受到关注带来的压力。

因此,让我们考虑 Web 应用程序的许多不同部分,以及它们中的每一个如何影响速度。

速度

诚然,网络可以有不同的速度。一般来说,人们用带宽来描述这一点,这实际上并不意味着电子(或光子)在电线(或光纤或空气)中移动得更快,而是意味着更多的电子(或光子)同时并行地通过。您可以将带宽想象成一根吸管,您正试图通过它喝您最喜欢的冷饮。两根吸管将允许您同时喝两倍的量,从而更快地饮用,即使液体流过每根吸管的速度相同。

使用共享服务器以及在共享硬件上使用虚拟机的一个潜在问题是,网络容量正在许多用户之间分配。想想如果几个人从之前的例子中分享您的饮用吸管会发生什么。当然,总体的吸管可能大小相同,但每个人获得的带宽都少于全部带宽。您也不需要虚拟机来看到这种效果——只需尝试在同一台计算机上运行几个网络密集型应用程序,您很快就会发现它们正在争夺网络资源。

这里的重点是,您希望最大化服务器可用的带宽。这意味着拥有您自己的服务器——即使它是 VM,您可能也不希望它与其他 VM 共享资源——并将不同的服务放在不同的计算机上。

延迟

这个术语也与速度有关,但方式与纯带宽不同。假设您想在两台大型服务器之间传输数据,因此您在这些网络之间放置了一条巨大的高速电线。您可以说这样的网络具有高带宽和低延迟,因为信号将通过高速电线在两者之间传输。

现在让我们用卫星链路替换高速电线。突然,由于将数据从一个网络发送到另一个网络需要时间,因此您降低了延迟,同时保持带宽不变。网络速度没有改变,但现在加载每个页面将花费更长的时间。Web 应用程序的主要考虑因素之一是延迟——服务器运行的网络的延迟,以及应用程序本身的延迟。如果服务器需要几秒钟才能回复,您可以说该应用程序具有高延迟。这不仅会让用户感到沮丧(他们必须等待服务器的响应),而且还意味着服务器上同时运行着更多的进程,消耗资源。因此,降低 Web 应用程序中的延迟符合用户和公司的最佳利益。

客户端等待时间

许多人,即使是那些使用 Web 多年的人,也不明白单个网页通常是数十个,有时甚至数百个不同文件的结果——通常来自不同的服务器。当然,有来自 Web 服务器的 HTTP 响应,但随后可能会(将)引用 JavaScript、CSS 和静态文件,这些文件可能位于各种位置。JavaScript 在这方面尤其臭名昭著,因为网站越来越多地从 Google Analytics、Optimizely、Facebook 等网站下载 JavaScript。

问题在于,为了显示完整的网页,您的浏览器需要检索所有这些单独的部分。因此,一个延迟的图像或一个延迟的 CSS 文件可能会导致用户端的等待时间令人沮丧地长。请注意,这只部分与服务器上的带宽和延迟有关。如果您的 Web 应用程序响应速度快如闪电,但告诉用户的浏览器从非常慢的服务器下载 JavaScript 文件,那么从用户的角度来看,事情可能会花费很长时间。

这意味着您需要以与以前可能不同的全新方式来考虑性能。仅仅将所有文件推送到用户的浏览器或指示用户的浏览器可以从中检索文件的站点是不够的。您还需要考虑它们的加载位置。页面顶部的 <script> 标签可能具有与页面底部的标签非常不同的性能特征,因为浏览器从上到下解释和呈现标签。

客户端性能

好像所有这些还不够,现在越来越成为富客户端 Web 应用程序的时代。无论您使用的是像 Backbone 这样简单的东西还是像 Ember.js 这样复杂的东西,您都在编写将在用户浏览器内执行的软件。在最初的二十年里,Web 高度偏向服务器,这也使其更容易扩展、分析、调试和改进程序。但是,现在程序在不同的浏览器中、在用户的计算机上运行,还有更多需要思考和担心的事情。

一个非常小的 JavaScript 程序可能会分配大量内存和/或花费很长时间才能运行。或者,一个非常大的 JavaScript 程序可能很简单,对浏览器内性能的影响很小。我越来越发现我的浏览器消耗了我计算机 CPU 的很大一部分——不是因为我做了很多事情,而是因为那里执行了大量的 JavaScript。

这一切意味着什么?

Web 开发曾经看起来如此简单。您获得一个域名,设置一台服务器,拼凑一些软件,然后就可以开展业务了。而且确实,您今天仍然可以这样做。但是,如果您期望一次获得大量访客,您需要了解您需要考虑、衡量然后优化的不同类型的“快速”。

下次,我将更深入地探讨每种类型的速度,查看软件中可能影响每种速度的特定部分。我将给出一些具体的建议,说明如何识别此类问题,以及如何解决这些问题,特别是如果您有一些唾手可得的成果。

Reuven M. Lerner 是一位资深的 Web 开发人员,提供 Python、Git、PostgreSQL 和数据科学方面的培训和咨询服务。他撰写了两本编程电子书(Practice Makes Python 和 Practice Makes Regexp),并为程序员发布免费的每周新闻通讯,网址为 http://lerner.co.il/newsletter。Reuven 的 Twitter 账号是 @reuvenmlerner,与他的妻子和三个孩子住在以色列的莫迪因。

加载 Disqus 评论