警告:本文内容是入门级的,大佬请按秩序有序撤离。php
原文地址:Web Architecture 101html
上图很好的展现了咱们在Storyblocks的架构。若是你是一个新手工程师,可能会以为这个架构很是复杂。在咱们深刻研究每一个组件的细节以前,首先应该对它们有个大概的了解。mysql
当一个用户在Google搜索“Strong Beautiful Fog And Sunbeams In The Forest”时,第一条结果来自Storyblocks,咱们主要的照片网站。用户点击结果就会在浏览器中跳转到图片详情页。在引擎下,用户的浏览器想DNS服务器发送一个请求,查询如何链接Storyblocks,而后向Storyblocks发送请求。web
请求会先到达咱们的负载均衡器,负载均衡器会随机选择一个正在运行的服务器来处理请求。服务器先从缓存中查找一部分关于图片的信息,并从数据库查找剩余信息。咱们注意到此时尚未对图片的颜色进行配置,所以咱们发送“color profile”任务到咱们的任务队列,处理任务的服务器会异步执行队列中的任务,而且将结果适时更新到数据库中。sql
接下来,咱们试图从使用照片标题在全文检索服务中找到与输入的照片类似的照片。若是登陆用户是Storyblocks的会员,咱们会去帐号服务中查找用户的相关信息。最后,咱们会把页面访问数据发送到数据“firehose”,以便存储到咱们的云存储系统上,并最终落地到数据仓库中。数据分析师会使用数据仓库中的数据来解决商业问题。mongodb
到这里,服务器已经呈现了一个HTML页面,并经过负载均衡器将它返回给用户。页面包含的JavaScript和CSS会放到链接了CDN的云存储系统中,因此用户的浏览器链接CDN取回数据。最后,由浏览器给用户呈现完整的页面。数据库
接下来,我会对每一个组件挨个进行简单的介绍,以求给你创建一个良好的关于学习架构的思惟模型。我会在另一个系列的文章中分享我在Storyblocks这段时间的实践经验,给你提供良好的建议。apache
DNS是“Domain Name System”的缩写,它是使万维网成为可能的核心技术。最基础的DNS提供了域名(例如google.com)和IP地址的(例如85.129.83.120)的键值对以供查找,这是计算机路由请求到指定服务器所必需的。类别电话号码,域名和IP地址的区别就像是“打给哲少”和“拨打201-867–5309”。就像过去你须要一个电话原本查找哲少的电话号码,现在你须要DNS服务器来查找域名对应的IP地址。因此你能够认为DNS就是互联网上的电话本。后端
关于DNS的细节咱们还能够展开讲不少,但这里咱们略过,由于这不是入门级介绍所关心的。浏览器
在介绍负载均衡器以前,咱们先来讨论一下应用的水平和垂直扩展。它们有什么不一样呢?这篇帖子介绍的很明白,水平扩展是经过向资源池中增长更多的机器,垂直扩展是在已有的机器中增长更高的配置(CPU、内存等)。
在Web开发中,为了应对服务器宕机,网络波动,数据中心不可用等突发状况,你必定常用横向扩展,由于它既简单又快捷。拥有一台以上的服务器使你的应用程序在部分服务器掉电时仍然能够正常运行。换句话说,你的程序具备较好的容错性。其次,横向扩展容许你经过让每一个部分运行在不一样的服务器上来解耦后端的依赖(Web服务器、数据库、服务 X等)。最后,当你的服务器达到必定规模时可能没法再进行垂直扩展。由于这个世界上没有任何一台计算机的性能好到能够支撑你全部应用的计算。举一个典型的栗子——Google的搜索平台。固然一原则对于多数规模较小的公司也适用,例如Storyblocks就部署了150到400个AWS EC2实例。对于这样的状况,要想经过垂直扩展来提供所有计算是一项艰难的挑战。
咱们再说回负载均衡器,它们使水平扩展成为可能。它们将传入进来的请求路由到众多服务器中的一个,并将响应结果返回给客户端。这些服务器一般是彼此的克隆或镜像,它们中的任何一个都应该以相同的方式处理,这样就经过分发请求的方式解决避免某台机器出现过载问题。
负载均衡的概念很是简单,可是实现起来很是复杂。咱们暂且不介绍。
在上层的Web应用服务描述起来很是简单。它们用来执行主要的业务逻辑,处理用户请求,并将HTML返回到用户的浏览器。为了完成任务,它们一般要与各类后端基础组件交互,好比数据库、缓存、任务队列、检索服务、其余微服务、数据/日志队列等等。如上所述,为了处理用户请求,你至少有两个,一般更多的负载均衡器。
你应该知道应用服务的实现须要选择一种语言(Node.js、Ruby、PHP、 Scala、 Java、 C# 、.NET等)和对应MVC框架(Node.js的Express,Ruby的Rails,Scala的Play,PHP的Laravel等)。然而深挖这些语言和框架的细节也超出了本文的讨论范围。
每一个Web应用项目都利用一个或多个数据库来存储信息。数据库提供了定义数据结构、对数据的增删改查、跨数据计算的方法。多数状况下,Web应用服务器和任务队列直接通讯。另外每一个后端服务可能都拥有独立的数据库。
虽然我一直强调本文不会介绍某个组件的细节,可是若是不提SQL和NOSQL也是一种不负责任的行为。
SQL的全称是“结构化查询语言”,它在18世纪70年代被发明。它给你们提供了查询关系型数据集的标准方法。SQL数据库将数据存储在经过公共ID(一般是整数)链接在一块儿的表中。让咱们来看一个存储用户历史地址信息的例子。你可能须要两张表,用户表和用户地址表,它们经过用户ID链接在一块儿。下图展现了一个简化版本。两个表经过外键链接。
若是你不是很了解SQL,我强烈推荐你学习一下Khan Academy的一门课程。SQL如今已经很是普及了,所以你至少要了解一些基础知识才能构建你的应用程序。
NoSQL表明“非SQL”,是一种新的数据库技术集,用于处理大规模Web应用产生的大量数据(大多数SQL不支持水平扩展,而且垂直扩展也只能扩展到某个点)。若是你不了解NoSQL,能够看下面这些介绍:
可是总的来讲,业界仍是要将SQL做为数据库的统一接口,即便是对菲关系型数据库,因此若是你还不了解SQL的话,就真的要赶快去学习一下了。
缓存服务提供了简单的kv存储数据,尽量使保存和查找数据的时间复杂度接近O(1)。应用程序通常把计算比较复杂的结果保存到缓存服务中,以便再次取值时直接从缓存中读取而不用从新进行复杂的计算。应用可能缓存的信息包括,数据库查询的结果,调用外部服务的返回值,一个URL返回的HTML等等。下面是一些实际的例子:
目前应用最普遍的两种缓存服务是Redis和Memcache。我会在另外一篇文章中对它们进行更深刻的介绍。
不少应用程序须要在后台异步处理一些和返回结果无关的逻辑。好比,Google为了提供搜索服务,须要爬取网页并进行索引。它并非在你每次搜索的时候都去作这件事,而是异步爬取,并更新索引。
虽然如今有不少不一样的架构都支持异步操做,但最普及的是我所说的“任务队列”架构。它包含两个组件:一个任务队列和至少一个任务服务器来执行队列中的任务。
任务队列一般保存一系列须要异步执行的任务。最简单的规则是先进先出(FIFO),大多数应用按照优先级给任务排序。当应用须要执行一个任务时,不管是定时任务仍是用户操做,都会把任务放到队列中去。
还拿Storyblocks举例,咱们使用一个后台的任务队列为咱们的市场提供支持。咱们会跑一些视频图片解码,处理CSV元数据标记,汇总用户统计信息,发送重置密码邮件等任务。咱们一开始采用FIFO的原则,后来改成优先级队列,以保证有些具备时效性的任务能尽快完成,好比发送重置密码邮件。
任务服务器用来处理任务。它们轮询任务队列以肯定是否有任务要执行以及是否有任务,若是有,就从任务队列中弹出一个任务来执行。底层语言和框架的选择很是多,但它们不在本文讨论范围。
许多web应用支持某种搜索功能——用户输入文本,应用返回“相关”的结果。支撑这种功能的技术通常称为全文检索,它利用反向索引快速找到包含关键字的文档。
如今某些数据库也支持检索功能(好比MySQL已经支持全文检索),一般是运行独立的搜索服务来计算和存储反向索引,并提供查询接口。目前最受欢迎的全文检索平台是Elasticsearch,另外还有一些其余比较好的平台 例如Sphinx和Apache Solr。
一旦一个APP达到必定的规模,就会有某些服务被独立出来运行。它们不会对外暴露,可是能够和应用内部的服务之间交互。Storyblocks有几个运营和计划的服务:
当下,一家公司的生死由他们驾驭数据的能力决定。现在几乎每一个APP一旦达到必定规模,就须要经过数据管道来收集、存储和分析数据。典型的管道有三个步骤:
另一个没有在架构图中画出来的一个步骤:将数据从应用程序和服务的操做数据库加载到数据仓库中。例如在Storyblocks,咱们每晚将VideoBlocks, AudioBlocks, Storyblocks, account service和贡献值门户网站的数据加载到Redshift。经过将核心业务数据与咱们的用户交互事件数据放在一块儿,为咱们的分析师提供了一整个数据集。
“云存储是一种简单、可靠且可扩展的存储、检索和共享数据的方法”——来自AWS。你可使用它存储或多或少的存储和访问本地文件系统的任何内容,而且能够经过HTTP上的RESTful API与其进行交互。Amazon的S3是目前最流行的云存储产品,也是咱们在Storyblocks普遍依赖的产品,用于存储咱们的视频、照片和音频资产,咱们的CSS和JavaScript,咱们的用户数据等等。
CDN的全称是“Content Delivery Network”,该技术提供了经过Web获取静态HTML,CSS,JavaScript和图像资源的方式,比直接从单个源服务器提供服务要快得多。它的工做原理是在世界各地的许多“边缘”服务器上分发内容,以便用户从“边缘”服务器而不是源服务器下载资源。例以下图中,一个用户从西班牙请求源服务器在纽约的网站,可是静态资源会从在英国的CDN边缘服务器加载,防止许多缓慢的跨大西洋HTTP请求。
这篇文章进行了更详尽的介绍。一般web应用应该始终使用CDN来提供CSS,JavaScript,图片,视频和其余资源。某些应用也可能利用CDN来提供静态HTML页面。
这是一篇入门级的Web架构总结。但愿可以对你有帮助。我但愿发布一系列的进阶文章,在接下来一两年内我会对这些组件进行深刻研究。