大型网站技术架构

网站架构其实并不难,真正能解决问题的技术一定是简单的。

February 23, 2017 - 3 minute read -
web develop

作为一名软件工程师,我们再解决问题之前,很有必要去认真思考面对的问题究竟是什么?有哪些技术方案可以选择?其基本原理是什么?只有弄清楚这些个问题,才能从根本上去解决问题。同样对于今天随处可以触及的网站问题也是这样,想做一名与web相关的技术人员,就不得不把网站的技术架构摸清楚,以不至于一遇到稍微有难度的问题后,就只会在Google/度娘上一顿乱Search,沦为编码是否成功全部靠运气的码农🙏!

1. 大型网站软件系统的特点

什么是大型网站?可能很难用一个标准去定义,这时候我们可以从它与传统企业应用系统相比,看出大型互联网应用系统有一下特点:

  • 高并发,大流量:需要面对高并发用户,大流量访问。Google日均PV数35亿,日均IP访问数3亿;腾讯QQ的最大在线用户数1.4亿(2011年数据);淘宝2012年“双11”活动一天交易额超过191亿,活动开始第一分钟独立访问用户达到1000万。
  • 高可用:系统7*24小时不间断服务。大型互联网网站的宕机时间通常会成为新闻焦点,例如2010年百度域名被黑客劫持导致不能访问,成为重大新闻热点。
  • 海量数据:需要存储、管理海量数据,需要使用大量的服务器。Facebook每周上传的照片数目接近10亿,百度收录的网页数目有数百亿,Google有近百万台服务器为全球用户提供服务。
  • 用户分布广泛,网络情况复杂:许多大型互联网都是为全球用户提供服务的,用户分布广泛,各地网络情况千差万别。在国内,还有各个运营商网络互通难的问题。而中美光缆数次故障,也让一些对国外用户依赖较大的网站不得不考虑在海外建立数据中心。
  • 安全环境恶劣:由于互联网的开放性,使得互联网网站更容易受到攻击,大型网站几乎每天都会被黑客攻击。2011年国内多个重要网站泄密用户密码,让普通用户也直面一次互联网安全问题。
  • 需求快速变更,发布频繁:和传统软件的版本发布频率不同,互联网产品为快速适应市场,满足用户需求,其产品发布频率极高。Office的产品版本以年为单位发布,而一般大型网站的产品每周都有新版本发布上线,至于中小型网站的发布就更频繁了,有时候一天会发布几十次。
  • 渐进式发展:与传统软件产品或者企业应用系统一开始就规划好全部的功能和非功能需求不同,几乎所有的大型互联网网站都是从一个小网站开始,渐进地发展起来的。Facebook是扎克伯克在哈佛大学的宿舍里开发的;Google的第一台服务器部署在斯坦福大学的实验室里;阿里巴巴则是在马云家的客厅里诞生的。好的互联网产品都是慢慢运营出来的,不是一开始就开发好的,这也正好与网站架构的发展演化过程对应的。

2. 大型网站架构演化发展历程

大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以P计的数据和面对数以亿计的用户,问题就会变得很棘手。大型网站架构主要即使解决这类问题,下面我们来看一个大型的网站是如何成长起来的?

2.1 初始阶段的网站架构

* 小型网站最开始时没有太多人访问,只需要一台服务器就绰绰有余。

初始阶段

应用程序、数据库、文件等所有的资源都在一台服务器上。通常服务器操作系统用Linux,应用程序用PHP开发,然后部署在Apache上,数据库使用MySQL,汇聚各种免费开源软件及一台廉价服务器就可以开始网站的发展之路了。

2.2 应用服务和数据服务分离阶段的网站架构

随之网站业务的发展,一台服务器逐渐不能满足需求:
* 越来越多的用户访问导致性能越来越差-并发处理能力差;
* 越来越多的数据导致存储空间不足;

* 这时就需要将应用和数据分离。

应用服务和数据服务分离

此时整个网站使用三台服务器:应用服务器,文件服务器和数据库服务器,三台服务器对硬件资源要求各不相同:应用服务器需要处理大量的业务逻辑,因此需要更快更强大的CPU,数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的硬盘和更大的内存,文件服务器需要存储大量的用户上传文件,因此需要更大的硬盘。

2.3 使用缓存改善网站性能阶段的网站架构

用户持续增多:
* 数据库压力太大导致访问延迟;
* 网站性能差,用户体验收到影响;

* 网站访问特点同样遵循二八定律:80%的业务访问集中在20%的数据上。
  数据缓存方案应运而生。

使用缓存改善网站性能

网站使用的缓存可以分为两种:缓存在应用服务器的本地缓存和缓存在专门的分布式缓存服务器上的远程缓存。本地缓存的访问速度更快一些,但是受应用服务器内存限制,缓存数据量有限。远程分布式缓存可以使用集群的方式,部署大内存的服务器作为专门的缓存服务器,可以在理论上做到不受内存容量的限制。

2.4 使用应用服务器集群改善网站的并发能力阶段的网站架构

* 当使用缓存将数据访问压力得到有效化解后,单一应用服务器能够
  处理的请求连接有限:网站访问高峰期,应用服务器成为整个网站的瓶颈;

* 使用集群是网站解决高并发、海量数据问题的常用手段。

使用应用服务器集群改善网站的并发能力

当有一台服务器的处理能力、存储空间不足时,不要企图去更换更强大的服务器,对于大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。此时,应该考虑增加一台服务器分担原有服务器的访问以及存储压力。

对网站架构而言,只要能通过增加一台服务器的方式改善负载压力,就可以以同样的方式持续增加服务器不断改善系统性能,从而式样系统的可伸缩性。应用服务器实现集群是网站可伸缩集群架构设计中较为简单成熟的一种方式。

通过负载均衡调度服务器,可将来自用户浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,如果有更多的用户,就在集群中加入更多的应用服务器,使应用服务器不在成为整个网站的瓶颈。

2.5 数据库读写分离阶段的网站架构

使用缓存将网站的绝大部分数据读操作可以不通过数据库就能完成,但是:
* 仍有一部分读操作需要访问数据库-缓存访问不命中、缓存过期;
* 全部的写操作需要访问数据库;
  
* 用户达到一定规模后,数据库因为负载过高而成为网站瓶颈,
  数据库读写分离功能该登场了。

数据库读写分离

目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库服务器的数据更新同步到另外一台服务器上,网站利用这一功能,实现数据库读写分离,从而改善数据库负载压力。为了便于应用程序访问读写分离后的数据库,通常在应用服务器端使用专门的数据访问模块,使数据库读写分离对应用透明。

2.6 使用反向代理和CDN加速网站响应阶段的网站架构

为了更好的用户体验,留着客户,网站需要加速访问速度,主要手段:
* 使用CDN;
* 使用反向代理;

使用反向代理和CDN加速网站响应

CDN和反向代理的基本原理都是缓存,区别在于CDN部署在网络提供商的机房,用户在请求时,能从最近的机房获取到资源;反向代理部署在网站的中心机房,当用户请求到达中心机房后,首先访问的是机房的反向代理服务器,如果反向代理服务器中存储了用户请求的资源,那么优先返回该部分资源给用户。两者的目的都是尽早返回数据给用户,一方面加快用户访问速度,另一方面也减轻后端服务器的负载压力。

2.7 使用分布式文件系统和分布式数据库系统阶段的网站架构

* 任何强大的单一服务器都满足不了大型网站持续增长的业务需求,
  这时需要使用分布式数据库。

使用分布式文件系统和分布式数据库系统

分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常大的时候才使用。一般情况下,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。

2.8 使用NoSQL和搜索引擎阶段的网站架构

* 随着网站业务越来越复杂,对数据存储和检索的需求也
  越来越复杂,网站需要采用一些非关系数据库技术如:
  NoSQL和非数据库查询技术如:搜索引擎。

使用NoSQL和搜索引擎

NoSQL和搜索引擎都是源自互联网的技术手段,对可伸缩性的分布式特性具有更好的支持。应用服务器则通过一个统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。

2.9 业务拆分阶段的网站架构

* 大型网站为了应对日益复杂的业务场景,通过使用分而治之的手段
  将整个网站业务分成不同的产品线,分归不通的业务团队负责。

业务拆分

具体到技术上,也会根据产品线划分,将一个网站拆分成许多不同的应用,每个独立部署维护。应用之间可以通过一个超链接建立关系,也可以通过消息队列进行数据分发,当然最多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。

2.10 分布式服务阶段的网站架构

* 随着业务拆分越来越小,存储系统越来越庞大;
* 应用系统的整体复杂程度呈指数级增加,部署维护越来越困难;
* 由于所有的应用要和所有的数据库系统连接,在数万台服务器规
  模的网站中,这些连接的数目是服务器规模的平方,导致数据库
  连接资源不足,拒绝服务。

* 既然每一个应用系统都需要执行许多相同的业务操作,比如用户管理,
  商品管理等,那么可以将这些共用的业务提取出来,独立部署。
* 由这些可复用的业务连接数据库,提供共用业务服务,而应用系统
  只需要管理用户界面,通过分布式服务调用共用业务服务完成具体
  业务操作。

分布式服务

大型网站的架构演化到这里,基本上大多数的技术问题都可以得到解决,诸如跨数据中心的实时数据同步和具体网站业务相关的问题也可以通过组合改进现有的技术架构来解决。

这个世界没有那个网站从诞生起就是大型网站,也没有哪个网站从发布起就有庞大的用户,高并发的访问以及海量的用户,大型网站都是从小型网站发展而来的。大型网站架构技术的核心价值不是从无到有建立一个网站,而是能够伴随小型网站业务的逐步发展,慢慢演化成一个大型网站,在此过程中,不需要放弃什么,不需要推翻什么,不需要剧烈的革命,就慢慢的把一个有=只有一台服务器,几百个用户的小网站演化成一个几十万台服务器,数十亿用户的大型网站。

3. 大型网站架构技术一览

网站系统架构层次 网站系统架构层次

3.1 前端架构

前端指用户请求到达网站应用服务器之前经历的环节,通常不包含网站业务逻辑,不处理动态内容。

  • 浏览器优化技术:并不是优化浏览器,而是通过优化响应页面,加快浏览器页面的加载和显示,常用的有页面缓存、合并HTTP请求减少请求次数、使用页面压缩等。
  • CDN:内容分发网络,部署在网络运营商机房,通过将静态页面内容分发到离用户最近的CDN服务器,使用户可以通过最短路径获取内容。
  • 动静分离,静态资源独立部署:静态资源,如JS、CSS等文件部署在专门的服务器集群上,和Web应用动态内容服务分离,并使用专门的(二级)域名。
  • 图片服务:图片不是指网站Logo、按钮图标等,这些文件属于上面提到的今天资源,应该和JS、CSS部署在一起。这里的图片指用户上传的图片,如产品图片、用户头像等,图片服务同样使用独立部署的图片服务器集群,并使用独立(二级)域名。
  • 反向代理:部署在网站机房,在应用服务器、静态资源服务器、图片服务器之前、提供页面缓存服务。
  • DNS:域名服务,将域名解析成IP地址,利用DNS可以实现DNS负载均衡,配置CDN也需要修改DNS,使域名解析后指向CDN服务器。

3.2 应用层架构

应用层是处理网站主要业务逻辑的地方

  • 开发框架:一个好的开发框架应该能够分离关注面,使得美工、开发工程师可以各司其职,易于协作。同时还应该内置一些安全策略,防护Web应用攻击。
  • 页面渲染:将分别开发维护的动态内容和静态模板集成起来,组合成最终显示给用户的完整页面。
  • 负载均衡:将多台应用服务器组成一个集群,通过负载均衡技术奖用户请求分发到不同的服务器上,以应对大量用户同事访问时产生的高并发负载压力。
  • Session管理:为了实现高可用的应用服务器集群,应用服务器通常设计为无状态,不保存用户请求上下文信息,但是网站业务通常需要保持用户会话信息,需要专门的机制管理Session,使得集群内甚至跨集群的应用服务器可以共享Session。
  • 动态页面静态化:对于访问量特别大而更新又不很频繁的动态页面,可以将其静态化,即生成一个静态页面,利用静态页面的优化手段加速用户访问,如反向代理、CDN、浏览器缓存等。
  • 业务拆分:将复杂而又庞大的业务拆分开来,形成多个规模较小的产品,独立开发、部署、维护,除了降低系统耦合度,也便于数据库业务分库。按业务对关系数据库进行拆分,技术难度相对较小,而效果又相对较好。
  • 虚拟化服务器:将一台物理服务器虚拟化成多台虚拟服务器,对于并发访问较低的业务,更容易用较少的资源构建高可用的应用服务器集群。

3.3 服务层架构

提供基础服务,供应用层调用,完成网站业务。

  • 分布式消息:利用消息队列机制,实现业务和业务、业务和服务之间的异步消息发送及低耦合的业务关系。
  • 分布式服务:提供高性能、低耦合、易复用、易管理的分布式服务,在网站实现面向服务架构(SOA)。
  • 分布式缓存:通过可伸缩的服务器集群提供大规模热点数据的缓存服务,是网站性能优化的重要手段。
  • 分布式配置:系统运行需要配置许多参数,如果这些参数需要修改,比如分布式缓存集群加入新的缓存服务器,需要修改应用程序客户端的缓存服务器列表配置,并重启应用程序服务器。分布式配置在系统运行期提供配置动态推送服务,将配置修改实时推送到应用系统,无需重启服务器。

3.4 存储层架构

提供数据、文件的持久化存储访问与管理服务。

  • 分布式文件:网站在线业务需要存储的文件大部分都是图片、网页、视频等比较小的文件,但是这些文件的数量非常庞大,而且通常都在持续增长,需要伸缩性设比较好的分布式文件系统。
  • 关系数据库:大部分网站的主要业务是基于关系数据库开发的,但是关系数据库对集群伸缩性的支持比较差。通过在应用程序的数据访问层增加数据库访问路由功能,根据业务配置将数据库访问路由到不同的物理数据库上,可实现关系数据库的分布式访问。
  • NoSQL数据库:目前各种NoSQL数据库层出不穷,在内存管理、数据模型、集群分布式管理等方面各有优势,不过从社区活跃性角度看,HBase无疑是目前不错的选择。
  • 数据同步:在支持全球范围内数据共享的分布式数据库技术成熟之前,拥有多个数据中心的网站必须在多个数据中心之间进行数据同步,以保证每个数据中心都拥有完整的数据。在实践中,为了减轻数据库压力,将数据库的事务日志(或者NoSQL的写操作Log)同步到其他数据中心,根据Log进行数据重演,实现数据同步。

3.5 后台架构

网站应用中,除了要处理用户的实时访问请求外,还有一些后台非实时数据分析要处理。

  • 搜索引擎:即使是网站内部的搜索引擎,也需要进行数据增量更新及全量更新、构建索引等。这些操作通过后台系统定时执行。
  • 数据仓库:根据离线数据,提供数据分析与数据挖掘服务。
  • 推荐系统:社交网站及购物网站通过挖掘人与人之间的关系,人和商品之间的关系,发掘潜在的人际关系和购物兴趣,为用户提供个性化推荐服务。

3.6 数据采集与监控

监控网站访问情况与系统运行情况,为网站运营决策和运维管理提供支持保障。

  • 浏览器数据采集:通过在网站页面中嵌入JS脚步采集用户浏览器环境与操作记录,分析用户行为。
  • 服务器业务数据采集:服务器业务数据包括两种,一种是采集在服务器端记录的用户请求操作日志;一种是采集应用程序运行期业务数据,比如待处理消息数目等。
  • 服务器性能数据采集:采集服务器性能数据,如系统负载、内存使用率、网卡流量等。
  • 系统监控:将前述采集的数据以图表的方式展示,以便运营和运维人员监控网站运行状况,做到这一步仅仅是系统监视。更先进的做法是根据采集的数据进行自动化运维,自动处理系统异常状况,实现自动化控制。
  • 系统报警:如果采集来的数据超过预设的正常情况的阈值,比如系统负载过高,就通过邮件、短信、语音电话等方式发出报警信号,等待工程师干预。

3.7 安全架构

保护网站免遭攻击及敏感信息泄露。

  • Web攻击:以HTTP请求的方式发起的攻击,危害最大的就是XSS和SQL注入攻击。
  • 数据保护:敏感信息加密传输与存储,保护网站和用户资产。

3.8 数据中心机房架构

大型网站需要的服务器规模数以十万计,机房物理架构也需要关注。

  • 机房架构:对于一个拥有十万台服务器的大型网站,每台服务器耗电(包括服务器本身耗电及空调耗电)每年大约需要2000¥,那么网站每年机房电费就要2B¥。数据中心能耗问题已经日趋严重,Google、Facebook选择数据中心地理位置的时候趋向选择散热良好,供电充裕的地方。
  • 机柜架构:包括机柜大小,网线布局、指示灯规格、不间断电源、电压规格(是48V直流电还是220V民用交流电)等一系列问题。
  • 服务器架构:大型网站由于服务器采购规模庞大,大都采用定制服务器的方式代替购买服务器整机。根据网站应用需求,定制硬盘、内存、甚至CPU,同时去除不必要的外设接口(显示器输出接口,鼠标、键盘输入接口),并使空间结构利于散热。

4. 写在最后

本人也算是生在互联网的时代,接触了各式各样的网站,同时自己也开发与维护网站,在遇到taobao李智慧老师的这本《大型网站技术架构》之前也一直希望能弄明白网站架构到底是怎么一回事,这本书对打开工程师的Web开发大局观有很大的帮助,是一本很全面的书。不过里面对很多技术细节探索都是点到即止,让人意犹未尽,其中也不乏认识比较浅的内容比如对安全部分的介绍少之又少。在此仅以此文致敬作者,接下来我会继续增加两篇关于web开发技术细节文章,敬请期待:高性能网站开发指南如果构建高性能Web网站
PS: 文中的图片摘自于简书大型网站架构演化, 谢谢!👏🏻