Web 应用架构基础课

栏目: 数据库 · 发布时间: 6年前

内容简介:上图便是我司(Storyblocks)网络架构的很好展现。如果你还没成为经验老道的 web 工程师,可能觉得上图巨复杂。在详解各个模块前,我们先简单过一下流程。用户在 Google 搜索关键字 “Strong Beautiful Fog And Sunbeams In The Forest”,

Web 应用架构基础课

上图便是我司(Storyblocks)网络架构的很好展现。如果你还没成为经验老道的 web 工程师,可能觉得上图巨复杂。在详解各个模块前,我们先简单过一下流程。

用户在 Google 搜索关键字 “Strong Beautiful Fog And Sunbeams In The Forest”, 首条结果 便是来自我司的拳头产品:Storyblocks —— 图片矢量图素材站,用户点击搜索结果进入图片详情页。在用户操作的背后,客户端浏览器向 DNS 服务器查询图片所在服务器,并发送访问请求。

用户请求通过负载均衡(随机选择多个服务器中的一个)访问站点处理请求。服务器从缓存服务中查找图片信息,并从数据库中调取其它信息。我们注意到此时,图片尚未进行色彩渲染计算,便发送“色彩渲染”任务到任务队列。此时该服务所在服务器异步处理任务,适时将结果更新到数据库。

接下来,我们尝试匹配相似图片,以图片标题作为输入,进行全文搜索服务。用户登入系统,系统通过账户服务查找账户信息。最后,系统将该页面查看事件作为日志流处理并在云存储系统中记录,再录入数据仓库,供数据分析师做之后的商业分析。

服务器将渲染的 HTML 页面先经过负载均衡,再返回到用户浏览器。页面包含 Javascript 脚本和 CSS 资源文件,存于与我们的 CDN 相连的云端存储系统中,用户浏览器直接通过 CDN 获取内容。最后,浏览器显式地渲染页面,供用户浏览。

下面,我们就每一个组件详细讨论,做最最基础的介绍,帮你建构认知模型,思考整个前面提到的整个网络服务架构。之后我还会发布其它文章,基于在我司学习到的内容,为大家更有针对性地从实践角度做推荐。

1. DNS

DNS(Domain Name Server)是域名服务器的简称,它是互联网依存的基础设施。简单来说,DNS 提供域名与 IP 地址的键值对查找,例如(google.com 域名对应 85.129.83.120 IP 地址),这非常有必要,它让你的电脑通过请求寻路到特定服务器。就好比打电话,域名与 IP 地址的关系类似于联系人和电话号码的关系。以前你需要电话号码簿记录他人的电话号码,现在你需要 DNS 服务器寻找域名对应的 IP 地址。所以你可以把 DNS 想象成互联网世界的电话簿。

这里我们还有很多细节可以深入,暂时先跳过,因为这不是我们基础课的重点。

2. 负载均衡

在详解负载均衡之前,我们先退一步讨论一下应用的纵向扩展和横向扩展。两者有什么区别?简单来说,参考 StackOverflow 的这篇帖子 ,横向规模扩展意味着通过在资源池中加机器,纵向扩展意味着在已有机器上增强算力(如 CPU,RAM)。

在 web 开发绝大多数情况下,会选择横向扩展。理由很简单,服务器会宕机,网络会断线,数据中心会掉电。多台服务器可以保证你的应用在能够一边停机维护,一边持续工作。换句话说,应用能够“容错”。另外,横向扩展能最小限度地耦合不同后台服务(web 服务器,数据库,等等),使不同服务在不同机器上运行。还有一点,纵向扩展是有上限的,到达一定限度就无法再扩展。世界上也不存在一台超算计算机承载应用的所有计算,典型例子想象一下 Google 的搜索平台,哪怕其它公司达不到这么大的规模。其它公司,比如我司,Storyblocks,任何时候都把服务跑在 150-400 个 AWS EC2 实例上。通过纵向扩展提供算力是相当有挑战的。

回到负载均衡,可以说它是横向扩展的黑魔法。它将传入请求转路到多个服务器中的其中一个,再将响应回传给客户端。多个服务器彼此作为镜像,任意机器都会以同样的方式处理请求。向服务集群分发消息,便不会出现单个服务器过载的情况。

理论上负载均衡就这些要点,很简单直接。当然了,简单的理论背后有更多细节,这篇入门文章里我们不再赘述。

3. Web 应用服务器

从上层角度来看,web 应用服务器相对好理解,它们用来处理核心业务逻辑,处理用户请求,给客户端浏览器返回 HTML。处理这些任务便是与后台基础设施间通信,比如数据库、缓存服务、任务队列、搜索服务、其它微服务和消息/日志队列等等。一般情况下至少两个应用服务器,或者更多,这些应用服务接入负载均衡,处理用户请求。

应用服务器的实现通常需要某种特定语言(Node.js, Ruby, PHP, Scala, Java, C# .NET 等)和对应的 MVC 框架上(Node.js 的 Express、Ruby on Rails、Scala 的 Play、 PHP 的 Larave 和 Java 的 Spring 等等)。语言和框架的细节我们这里不做赘述,有兴趣的读者可以自行深入研究。

4. 数据库服务器

任意现代 Web 应用都使用一个甚至多个数据库来存储信息。数据库用来定义数据结构,对数据进行增删改查,高级运算操作等等。多数情况下,web 应用服务器与一个数据库进行直接通信,任务服务器同理。另外,每个后台服务都有一个自己的数据库,并与其它的应用隔离。

尽管在本文中,我们尽量避免深入讨论架构中的某个特定技术,这里我还是想特殊地提一下数据库中的 SQL 和 NoSQL。

SQL(Structured Query Language)全称结构化查询语言,1970 年代发布,提供了查询关系型数据库的一种标准形式,并广为大众接受。SQL 数据库将数据以表的形式存储,通过 ID (通常为 int 整型)这种方式使表之间相互关联。举个简单的例子,我们想要存储用户的历史地址信息。需要准备两张表,用户表 users 和用户地址表 user_addresses,并通过 user_id 进行关联,如下图。表间相关联是通过在 user_addresses 表中使用 user_id 作为外键实现的。

Web 应用架构基础课

如果你不了解 SQL,这里推荐 可汗学院的课程学习

。在 web 开发中 SQL 非常普遍,了解其基础作为应用架构还是很有必要的。

NoSQL,如其字面意思,“非-SQL”,是一种新型数据库,用来应对大规模 web 应用中的海量数据(大部分 SQL 不能很好支持横向扩展,只能从某些方面支持纵向扩展)。如果你完全不了解 NoSQL,推荐下列文章:

我还想顺便提一点, 业界通常使用 SQL 作为 NoSQL 数据库的表层调用 ,不懂 SQL 的话还是很有必要去学习的,如今的业务场景很难避开它。

5. 缓存服务

缓存服务提供一种简单的键值对数据存储,使存取信息时间复杂度接近 O(1) 。应用内通常使用缓存服务存储运算成本高昂的运算结果,再次请求时从缓存中检索结果,而非在每次请求时都重新计算。缓存内容可以是数据库查询,外部服务调用结果,链接返回的 HTML,等等。下面我们从真实场景中举例:

  • 搜索引擎服务(比如百度)会缓存一些常见的查询结果,比如“狗”,“周杰伦”,而不是在每次查询时都实时计算。
  • 社交网站服务(比如 Facebook)会缓存每次登陆时用户看到的数据,比如最近博文,好友,等等。这里有一篇 Facebook 如何做缓存 的文章。
  • 我司(Storyblocks)会缓存服务器端 React 渲染的 HTML 页面,搜索结果,预输入结果,等等。

最常用到的服务器缓存技术是 Redis 和 Memcache。我之后会在其它文章中深入讨论。

6. 任务队列及服务器

大部分 web 应用背后都有异步任务在处理,这些任务不必直接响应用户请求。比如说,谷歌需要爬取整个互联网并建立索引以返回搜索结果,但这实际上并不是在你每次搜索时都实时进行,而是通过异步方式爬取网络结果并更新索引。

异步任务有很多不同的方式来完成,最常用的是任务队列。它包含两部分:正在运行的任务队列,和一或多个处理任务的服务器(通常称为 workers)。

任务队列存储了一系列需要异步运行的任务。最简单的任务调度是 FIFO(先进先出)的方式,不过大部分应用使用按优先级 排序 的调度方式处理任务。每当一个任务需要被执行,要么使用统一的调度算法,要么是按用户行为按需调度,该任务便被加入队列中等待被执行。

举个例子,我司利用任务队列,赋能后台任务以支持营销活动。我们用后台任务编码多媒体文件如视频图片,处理数据如在 CSV 做元数据标记,聚合用户行为分析,运行邮件服务比如给用户发送重置密码的邮件,等等。我们最初使用 FIFO 调度任务,后来优化为优先队列,以保证时间敏感的操作完成的实时性,比如立马发送重置密码邮件。

任务服务器执行任务时,先查看任务队列中是否有任务需要执行,若有任务便弹出该任务并执行。有很多语言和框架可以在服务器上使用作为任务队列,这里不多讲。

7. 全文检索服务

在一些应用中,为用户提供搜索功能,用户输入文字时(查询语句)应用返回相近结果。这种技术通常指的是“ 全文检索 ”,运用 倒排索引 快速查找包含查询关键字的文档。

Web 应用架构基础课

上图中例子显示了三个文档标题被转换成倒排索引,通过某些标题关键字能够快速检索文档。通常停用词(英文中的:in、the、with 等,中文中:我、这、和、啊等)不会被加入到索引中。

尽管我们可以直接通过数据库做全文检索,比如 MySQL 支持全文检索 ,但通常我们会跑一个单独的“搜索服务”计算并存储倒排索引,并提供查询接口。目前主流的全文检索服务是 Elasticsearch ,还有 SphinxApache Solr 等选择。

8. 服务

当应用到达一定的规模,通常倾向于拆分其为单个应用,作为“微服务”。外界对这些微服务是不可感知的,但应用内服务间相互通信。比如我司有各种运维服务和计划执行服务:

  • 用户服务 存储所有平台网站用户数据,便捷地提供交叉销售商机,以及统一的用户体验。
  • 内容服务 存储多媒体文件的元数据,并提供文件下载接口和下载历史信息等。
  • 支付服务 提供客户付款信息接口。
  • PDF导出服务 提供统一接口,将 HTML 转换成相对应的 PDF 文件并下载。

9. 数据

如今各大公司成败在于 “如何很好地管理数据”,在应用到达一定规模时规范数据流程。一般来说有:加工数据、存储数据和分析数据,这三个步骤:

  1. 数据加工 应用响应用户交互事件,将数据发送到数据流处理平台(提供流数据处理接口)进行处理。通常原始数据被转换或加工并传入另一个数据流处理平台。AWS Kinesis 和 Kafka 是此类数据流处理最常用的工具。
  2. 数据存储 原始数据和转换加工后的数据在云端存储。例如 AWS Kinesis 提供叫做 “firehose” 的配置,将原始数据存储在其云平台 Amazon S3 上,使用起来极其方便。
  3. 数据分析 转换加工后的数据会加载入数据仓库来做后续分析。我司使用 AWS Redshift 作为数据仓库,很多创业公司也都在用,大型公司一般选择 Oracle 或者其它的数据仓库服务。当数据量十分庞大时,可能需要用类 Hadoop 的 NoSQL MapReduce 技术来做后续分析。

还有一个步骤没有在架构图中绘出:从应用和服务运维数据库中把数据导入数据仓库。例如在我司,我们每晚都会把各个服务的数据存到 AWS Redshift,把核心业务的数据和用户交互行为的数据放在一起,提供给我们的数据分析师一个整体化的数据集。

10. 云存储

“云存储既简单,扩展性又好,方便用户在全网获取、存储、分享数据” —— AWS 云存储服务 。任意在本地文件系统存储的文件,你都可以通过云存储存取,并用 HTTP 协议通过 RESTful API 访问并交互。Amazon S3 提供了目前最流行的云存储,我司在其上广泛存储各种东西,从多媒体素材、视频、图片、音频,到 CSS、Javascript 乃至用户行为数据等等。

11. CDN

CDN 指的是内容分发网络,该技术提供一种素材服务,比如存储静态 HTML,CSS,Javascript 和图片。从全网获取这些静态素材比从单个源服务器获取要快的多。它的工作原理是将内容分布在世界各地的边缘服务器上,而不是仅仅放在一个源节点上。比如说,下图中一个西班牙的用户访问某个源节点位于纽约的网站,但是页面的静态素材通过英国的 CDN 边缘服务器载入,这样就避免了冗余的跨大西洋的 HTTP 请求,提快了访问速度。

Web 应用架构基础课

这篇文章 更详细解释了为什么使用 CDN。总的来说,网络应用可以使用 CDN 来存储诸如 CSS、Javascript 和图片视频等素材,甚至静态 HTML 网页。

一些想法

以上便是网络应用架构基础课的全部内容,希望这篇文章对你有帮助。接下来我还会发布进阶课的文章,详细研究上述的某些组件。

原文: Web Architecture 101

译文: Web 应用架构基础课


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java程序设计

Java程序设计

宋中山 严千钧 等编 / 清华大学出版社 / 2005-8 / 27.00元

本书全面、系统地介绍了Java语言的基本概念、基本语法和编程方法。主要内容包括:Java语言概述、数据类型与运算符、流程控制语句、类与对象、继承与多态、异常处理、工具类和算法、Applet小应用程序、图形用户界面、输入和输出、Java多线程以及Java高级编程。每章后面附有习题,读者可参考使用。 本书内容丰富,结构合理,语言简洁,深入浅出,通俗易懂。基础知识与程序实例相结合,示例典型......一起来看看 《Java程序设计》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码