网页架构 101

一位用户在谷歌上搜索“森林中强烈的美丽雾和阳光”。第一个结果恰好来自故事块,我们领先的库存照片和矢量网站。用户单击结果,将其浏览器重定向到图像详细信息页面。在引擎盖下,用户的浏览器向 DNS 服务器发送请求,以查找如何联系 Storyblocks,然后发送请求。

该请求命中我们的负载均衡器,该负载均衡器随机选择我们当时运行该网站的10个左右的Web服务器之一来处理请求。Web服务器从我们的缓存服务中查找有关图像的一些信息,并从数据库中获取有关它的其余数据。我们注意到图像的颜色配置文件尚未计算,因此我们将“颜色配置文件”作业发送到作业队列,我们的作业服务器将异步处理该作业,并使用结果相应地更新数据库。

接下来,我们尝试通过使用照片的标题作为输入向我们的全文搜索服务发送请求来查找类似的照片。用户碰巧是作为会员登录Storyblocks的用户,因此我们从我们的帐户服务中查找他的帐户信息。最后,我们触发一个页面视图事件到我们的数据消防水管,记录在我们的云存储系统上,并最终加载到我们的数据仓库中,分析师用它来帮助回答有关业务的问题。

服务器现在将视图呈现为 HTML,并将其发送回用户的浏览器,首先通过负载均衡器。该页面包含我们加载到云存储系统中的Javascript和CSS资产,该存储系统连接到我们的CDN,因此用户的浏览器会联系CDN以检索内容。最后,浏览器以可视方式呈现页面以供用户查看。

接下来,我将引导您完成每个组件,为每个组件提供“101”介绍,这应该为您提供一个很好的思维模型,以便您思考Web架构。我将跟进另一系列文章,根据我在 Storyblocks 期间学到的知识提供具体的实现建议。

1. 域名解析

DNS代表“域名系统”,它是使万维网成为可能的骨干技术。在最基本的级别上,DNS 提供从域名(例如,google.com)到 IP 地址(例如 85.129.83.120)的键/值查找,这是您的计算机将请求路由到相应服务器所必需的。与电话号码类似,域名和IP地址之间的区别是“呼叫John Doe”和“呼叫201-867-5309”之间的区别。就像过去您需要电话簿来查找John的号码一样,您需要DNS来查找域的IP地址。因此,您可以将DNS视为互联网的电话簿。

我们可以在这里介绍更多细节,但我们会跳过它,因为它对我们的101级介绍并不重要。

2. 负载均衡器

在深入了解负载平衡之前,我们需要退后一步来讨论水平与垂直应用程序扩展。它们是什么,有什么区别?非常简单地放在StackOverflow帖子中,水平扩展意味着您可以通过向资源池中添加更多计算机来扩展,而“垂直”扩展意味着通过向现有计算机添加更多功率(例如CPU,RAM)来扩展。

在Web开发中,你(几乎)总是想要水平扩展,因为为了保持简单,东西会中断。服务器随机崩溃。网络降级。整个数据中心偶尔会脱机。拥有多台服务器允许您规划中断,以便应用程序继续运行。换句话说,你的应用是“容错的”。其次,水平扩展允许您通过将应用程序后端的不同部分(Web 服务器、数据库、服务 X 等)分别在不同的服务器上运行来最小化耦合。最后,您可能会达到无法再垂直缩放的刻度。世界上没有一台计算机大到足以执行应用的所有计算。将Google的搜索平台视为一个典型的例子,尽管这适用于规模小得多的公司。例如,故事块在任何给定时间点运行 150 到 400 个 AWS EC2 实例。通过垂直扩展提供整个计算能力将是一项挑战。

好了,回到负载均衡器。它们是使水平缩放成为可能的神奇酱汁。它们将传入的请求路由到许多应用程序服务器之一,这些应用程序服务器通常是彼此的克隆/镜像映像,并将响应从应用程序服务器发送回客户端。他们中的任何一个都应该以相同的方式处理请求,因此只需在一组服务器之间分发请求,这样它们就不会过载。

就是这样。从概念上讲,负载均衡器是相当直接的。在引擎盖下,肯定会有并发症,但没有必要深入研究我们的101版本。

3. 网络应用程序服务器

在高级Web应用程序服务器相对容易描述。它们执行处理用户请求并将 HTML 发送回用户浏览器的核心业务逻辑。为了完成他们的工作,他们通常与各种后端基础架构进行通信,例如数据库,缓存层,作业队列,搜索服务,其他微服务,数据/日志记录队列等。如上所述,您通常至少有两个并且通常更多,插入负载均衡器以处理用户请求。

您应该知道,应用程序服务器实现需要为该语言选择特定的语言(节点.js,Ruby,PHP,Scala,Java,C# .NET等)和该语言的Web MVC框架(节点快速.js,轨道上的Ruby,斯卡拉的播放,PHP的Laravel等)。但是,深入探讨这些语言和框架的详细信息超出了本文的范围。

4. 数据库服务器

每个现代 Web 应用程序都利用一个或多个数据库来存储信息。数据库提供了定义数据结构、插入新数据、查找现有数据、更新或删除现有数据、对数据执行计算等方法。在大多数情况下,Web 应用服务器直接与一个服务器通信,作业服务器也是如此。此外,每个后端服务可能都有自己的数据库,该数据库与应用程序的其余部分隔离。

虽然我避免深入研究每个架构组件的特定技术,但我不会对你说一个坏处,更不用说数据库的下一个细节层次:SQL和NoSQL。

SQL代表“结构化查询语言”,发明于20世纪70年代,旨在提供一种查询关系数据集的标准方法,可供广大受众访问。SQL 数据库将数据存储在通过通用 ID(通常为整数)链接在一起的表中。让我们通过一个为用户存储历史地址信息的简单示例。您可能有两个表(用户表和user_addresses表)通过用户的 ID 链接在一起。有关简单化版本,请参阅下图。之所以链接这些表,是因为user_addresses中的user_id列是用户表中 id 列的“外键”。

如果你对SQL了解不多,我强烈建议你通过一个教程,你可以在这里找到可汗学院。它在Web开发中无处不在,因此您至少想知道基础知识,以便正确构建应用程序。

NoSQL代表“非SQL”,是一组较新的数据库技术,已经出现,用于处理大规模Web应用程序可能产生的大量数据(SQL的大多数变体不能很好地水平扩展,只能垂直扩展到某个点)。如果您对NoSQL一无所知,我建议您从一些高级介绍开始,例如:

https://www.w3resource.com/mongodb/nosql.php

http://www.kdnuggets.com/2016/07/seven-steps-understanding-nosql-databases.html

https://resources.mongodb.com/getting-started-with-mongodb/back-to-basics-1-introduction-to-nosql

我还要记住,总的来说,即使对于NoSQL数据库,业界也在将SQL作为接口进行调整,因此如果您不知道SQL,那么您真的应该学习SQL。如今,几乎没有办法避免它。

5. 缓存服务

缓存服务提供了一个简单的键/值数据存储,可以在接近O(1)的时间内保存和查找信息。应用程序通常利用缓存服务来保存昂贵计算的结果,以便可以从缓存中检索结果,而不是在下次需要时重新计算它们。应用程序可能会缓存来自数据库查询、对外部服务的调用、给定 URL 的 HTML 等的结果。以下是来自实际应用程序的一些示例:

Google会缓存常见搜索查询(如“狗”或“泰勒·斯威夫特”)的搜索结果,而不是每次都重新计算它们

Facebook会缓存您在登录时看到的大部分数据,例如帖子数据,朋友等。在这里阅读有关 Facebook 缓存技术的详细文章。

故事块缓存来自服务器端 React 呈现、搜索结果、键入结果等的 HTML 输出。

两种最普遍的缓存服务器技术是雷迪斯和梅麦卡切。我将在另一篇文章中更详细地介绍。

6. 作业队列和服务器

大多数 Web 应用程序需要在后台异步执行一些与响应用户请求没有直接关联的工作。例如,谷歌需要抓取整个互联网并将其编入索引才能返回搜索结果。它不会在每次搜索时都这样做。相反,它会异步抓取 Web,并在此过程中更新搜索索引。

虽然有不同的架构可以完成异步工作,但最普遍的是我所称的“作业队列”架构。它由两个组件组成:需要运行的“作业”队列和运行队列中作业的一个或多个作业服务器(通常称为“工作线程”)。

作业队列存储需要异步运行的作业的列表。最简单的是先进先出(FIFO)队列,尽管大多数应用程序最终需要某种优先级排队系统。每当应用需要运行作业时(无论是按照某种常规计划还是根据用户操作确定),它只需将相应的作业添加到队列中即可。

例如,Storyblocks利用作业队列来支持我们的市场所需的许多幕后工作。我们运行作业来对视频和照片进行编码,处理 CSV 以进行元数据标记,汇总用户统计信息,发送密码重置电子邮件等。我们从一个简单的FIFO队列开始,尽管我们升级到了优先级队列,以确保及时完成时间敏感的操作,如发送密码重置电子邮件。

作业服务器处理作业。它们轮询作业队列以确定是否有工作要做,如果有,它们会从队列中弹出作业并执行它。基础语言和框架的选择与Web服务器一样多,因此我不会在本文中深入探讨。

7. 全文搜索服务

许多(如果不是大多数)Web 应用都支持某种搜索功能,其中用户提供文本输入(通常称为“查询”),并且应用返回最“相关”的结果。支持此功能的技术通常称为“全文搜索”,它利用倒排索引快速查找包含查询关键字的文档。

显示如何将三个文档标题转换为倒排索引的示例,以便于从特定关键字快速查找标题中包含该关键字的文档。请注意,常用词如“in”、“the”、“with”等(称为非索引)通常不包含在倒排索引中。

虽然可以直接从某些数据库进行全文搜索(例如,MySQL支持全文搜索),但通常运行单独的“搜索服务”来计算和存储倒排索引并提供查询接口。今天最受欢迎的全文搜索平台是弹性搜索,尽管还有其他选择,如狮身人面像或Apache Solr。

8. 服务

一旦应用程序达到一定规模,可能会有某些“服务”被雕刻出来作为单独的应用程序运行。它们不会暴露在外部世界中,但应用和其他服务会与它们进行交互。例如,故事块具有多个操作和计划服务:

帐户服务将用户数据存储在我们的所有站点中,这使我们能够轻松提供交叉销售机会并创建更统一的用户体验

内容服务存储我们所有视频、音频和图像内容的元数据。它还提供了用于下载内容和查看下载历史记录的界面。

支付服务提供了用于向客户信用卡开具账单的接口。

HTML → PDF 服务提供了一个简单的界面,该界面接受 HTML 并返回相应的 PDF 文档。

9. 数据

如今,公司的生存和死亡取决于他们利用数据的能力。如今,几乎每个应用程序,一旦达到一定规模,就会利用数据管道来确保可以收集,存储和分析数据。典型的管道有三个主要阶段:

该应用程序将数据(通常是有关用户交互的事件)发送到数据“firehose”,该数据“firehose”提供用于引入和处理数据的流式处理接口。通常,原始数据被转换或增强并传递到另一个消防水管。AWS Kinesis 和卡夫卡是用于此目的的两种最常见的技术。

原始数据以及最终的转换/增强数据将保存到云存储中。AWS Kinesis 提供了一种称为“消防水管”的设置,使将原始数据保存到其云存储 (S3) 中变得非常容易配置。

转换/增强的数据通常加载到数据仓库中进行分析。我们使用 AWS Redshift,创业界中很大一部分人也是如此,尽管大型公司通常会使用 Oracle 或其他专有仓库技术。如果数据集足够大,则可能需要类似Hadoop的NoSQL映射还原技术进行分析。

体系结构图中未描述的另一个步骤:将数据从应用和服务的操作数据库加载到数据仓库中。例如,在故事块中,我们每天晚上都会将视频块、音频块、故事块、帐户服务和贡献者门户数据库加载到 Redshift 中。通过将核心业务数据与我们的用户交互事件数据放在一起,这为我们的分析师提供了一个整体数据集。

10. 云存储

“云存储是通过互联网存储、访问和共享数据的一种简单且可扩展的方式”,AWS 表示。您可以使用它来存储和访问或多或少存储在本地文件系统上的任何内容,其好处是通过HTTP通过RESTful API与它进行交互。亚马逊的S3产品是迄今为止最受欢迎的云存储,也是我们在Storyblocks上广泛依赖的云存储,用于存储我们的视频,照片和音频资产,我们的CSS和Javascript,我们的用户事件数据等等。

11. 加速网络

CDN代表“内容交付网络”,该技术提供了一种通过Web提供静态HTML,CSS,Javascript和图像等资产的方法,比从单个源服务器提供它们要快得多。它的工作原理是将内容分发到世界各地的许多“边缘”服务器上,以便用户最终从“边缘”服务器而不是源服务器下载资产。例如,在下图中,西班牙的用户从位于纽约市的源服务器站点请求网页,但该页面的静态资产是从英格兰的CDN“边缘”服务器加载的,从而阻止了许多缓慢的跨大西洋HTTP请求。


首页 > 新闻资讯

留言