大型网站架构

为了解决大型网站面临的高并发访问、海量数据处理、高可靠运行等一系列问题与挑战,大型互联网公司在实践中提出了许多解决方案,以实现网站高性能、高可用、易伸缩、可扩展、安全等各种技术架构目标。这些解决方案又被更多网站重复使用,从而逐渐形成大型网站架构模式。分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对比较单一的职责,然后通过上层对下层的依赖和调用组成一个完整的系统。分层结构在计算机世界中无处不在,网络的 7层通信协议是一种分层结构;计算机硬件、操作系统、应用软件也可以看作是一种分层结构。在大型网站架构中也采用分层结构,将网站软件系统分为应用层(负责具体业务和视图展示,如网站首页及搜索输入和结果展示)、服务层(为应用层提供服务支持,如用户管理服务,购物车服务等)、数据层(提供数据存储访问服务,如数据库、缓存、文件、搜索引擎等)。通过分层,可以更好地将一个庞大的软件系统切分成不同的部分,便于分工合作开发和维护;各层之间具有一定的独立性。

分割

如果说分层是将软件在横向方面进行切分,那么分割就是在纵向方面对软件进行切分。大型网站分割的粒度可能会很小。比如在应用层,将不同业务进行分割,例如将购物、论坛、搜索、广告分割成不同的应用,由独立的团队负责,部署在不同服务器上;在同一个应用内部,如果规模庞大业务复杂,会继续进行分割,比如购物业务,可以进一步分割成机票酒店业务、3C 业务, 小商品业务等更细小的粒度。

分布式

对于大型网站,分层和分割的一个主要目的是为了切分后的模块便于分布式部署,即将不同模块 部署在不同的服务器上,通过远程调用协同工作。分布式意味着可以使用更多的计算机完成同样的功能,计算机越多,CPU、内存、存储资源也就越多,能够处理的并发访问和数据量就越大,进而能够为更多的用户提供服务。但分布式在解决网站高并发问题的同时也带来了其他问题。首先,分布式意味着服务调用必须通过网络,这可能会对性能造成比较严重的影响;其次,服务器越多,服务器宕机的概率也就越大。 常用的分布式方案有以下几种:

  • 分布式应用和服务:将分层和分割后的应用和服务模块分布式部署,除了可以改善网站性能和并发性、加快开发和发布速度、减少数据库连接资源消耗外;还可以使不同应用复用共同的服务,便于业务功能扩展。
  • 分布式静态资源:网站的静态资源如 JS,CSS,Logo 图片等资源独立分布式部署,并采用独立的域名,即人们常说的动静分离。静态资源分布式部署可以减轻应用服务器的负载压力;通过使用独 立域名加快浏览器并发加载的速度;
  • 分布式数据和存储:大型网站需要处理以 P 为单位的海量数据,单台计算机无法提供如此大的存储空间,这些数据需要分布式存储。除了对传统的关系数据库进行分布式部署外,为网站应用而生的 各种 NoSQL产品几乎都是分布式的。
  • 分布式计算:严格说来,应用、服务、实时数据处理都是计算,网站除了要处理这些在线业务,还有很大一部分用户没有直观感受的后台业务要处理,包括搜索引擎的索引构建、数据仓库的数据分析统计等。这些业务的计算规模非常庞大,目前网站普遍使用 Hadoop及其MapReduce分布式计算框架进行此类批处理计算,其特点是移动计算而不是移动数据,将计算程序分发到数据所在的位置以加速计算和分布式计算。

集群

使用分布式虽然已经将分层和分割后的模块独立部署,但是对于用户访问集中的模块(比如网站首页),还需要将独立部署的服务器集群化,即多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务。因为服务器集群有更多服务器提供相同服务,因此可以提供更好的并发特性,当有更多用户访问的时候,只需要向集群中加入新的机器即可。同时因为一个应用由多台服务器提供,当某台服务器发生故障时,负载均衡设备或者系统的失效转移机制会将请求转发到集群中其他服务器上,使服务器故 障不影响用户使用。所以在网站应用中,即使是访问量很小的分布式应用和服务,也至少要部署两台服务器构成一个小的集群,目的就是提高系统的可用性

缓存

缓存就是将数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,现代CPU越来越快的一个重要因素就是使用了更多的缓存,在复杂的软件设计中,缓存几乎无处不在。大型网站架构设计在很多方面都使用了缓存设计。

  • CDN:即内容分发网络,部署在距离终端用户最近的网络服务商,用户的网络请求总是先到达他的网络服务商那里,在这里缓存网站的一些静态资源(较少变化的数据),可以就近以最快速度返回 给用户,如视频网站和门户网站会将用户访问量大的热点内容缓存在CDN。
  • 反向代理:反向代理属于网站前端架构的一部分,部署在网站的前端,当用户请求到达网站的数据中心时,最先访问到的就是反向代理服务器,这里缓存网站的静态资源,无需将请求继续转发给应用服务器就能返回给用户。
  • 本地缓存:在应用服务器本地缓存着热点数据,应用程序可以在本机内存中直接访问数据,而无需访问数据库。
  • 分布式缓存:大型网站的数据量非常庞大,即使只缓存一小部分,需要的内存空间也不是单机能 承受的,所以除了本地缓存,还需要分布式缓存,将数据缓存在一个专门的分布式缓存集群中,应用 程序通过网络通信访问缓存数据。

使用缓存有两个前提条件,一是数据访问热点不均衡,某些数据会被更频繁的访问,这些数据应该放在缓存中;二是数据在某个时间段内有效,不会很快过期,否则缓存的数据就会因已经失效而产生脏读,影响结果的正确性。网站应用中,缓存除了可以加快数据访问速度,还可以减轻后端应用和数据存储的负载压力,这一点对网站数据库架构至关重要,网站数据库几乎都是按照有缓存的前提进行负载能力设计的。

异步

计算机软件发展的一个重要目标和驱动力是降低软件耦合性。事物之间直接关系越少,就越少被彼此影响,越可以独立发展。大型网站架构中,系统解耦合的手段除了前面提到的分层、分割、分布等,还有一个重要手段是异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作。 在单一服务器内部可通过多线程共享内存队列的方式实现异步,处在业务操作前面的线程将输出写入到队列,后面的线程从队列中读取数据进行处理;在分布式系统中,多个服务器集群通过分布式 消息队列实现异步,分布式消息队列可以看作内存队列的分布式部署。

冗余

网站需要7*24小时连续运行,但是服务器随时可能出现故障,特别是服务器规模比较大时,出现某台服务器宕机是必然事件。要想保证在服务器宕机的情况下网站依然可以继续服务,不丢失数据, 就需要一定程度的服务器冗余运行,数据冗余备份,这样当某台服务器宕机时,可以将其上的服务和数据访问转移到其他机器上。访问和负载很小的服务也必须部署至少两台服务器构成一个集群,其目的就是通过冗余实现服务高可用。

自动化

在无人值守的情况下网站可以正常运行,一切都可以自动化是网站的理想状态。目前大型网站的自动化架构设计主要集中在发布运维方面。发布对网站都是头等大事,许多网站故障出在发布环节,网站工程师经常加班也是因为发布不顺利。通过减少人为干预,使发布过程自动化可有效减少故障。发布过程包括诸多环节。自动化代码管理,代码版本控制、代码分支创建合并等过程自动化,开发工程师只要提交自己参与开发的产品代号,系统就会自动为其创建开发分支,后期会自动进行代码合并;自动化测试,代码开发完成,提交测试后,系统自动将代码部署到测试环境,启动自动化测试用例进行测试,向相关人员发送测试报告,向系统反馈测试结果。

安全

网站在安全架构方面也积累了许多模式:通过密码和手机校验码进行身份认证;登录、交易等操作需要对网络通信进行加密,网站服务器上存储的敏感数据如用户信息等也进行加密处理;为了防止机器人程序滥用网络资源攻击网站,网站使用验证码进行识别;对于常见的用于攻击网站的XSS攻击、SQL注入、进行编码转换等相应处理; 对于垃圾信息、敏感信息进行过滤;对交易转账等重要操作根据交易模式和交易信息进行风险控制。

高性能架构

两个网站性能架构设计方案:A 方案和 B 方案,A 方案在小于100个并发用户访问时,每个请求的响应时间是1秒,当并发请求达到200的时候,请求的响应时间将骤增到 10 秒。B方案不管是100个并发用户访问还是200个并发用户访问,每个请求的响应时间都差不多是1.5秒。哪个方案的性能好?网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标,同时也是主观的感受。 不同视角下的网站性能有不同的标准,也有不同的优化手段。从用户角度,网站性能就是用户在浏览器上直观感受到的网站响应速度快还是慢。用户感受到的时间,包括用户计算机和网站服务器通信的时间、网站服务器处理的时间、用户计算机浏览器构造请求解析响应数据的时间。开发人员关注的主要是应用程序本身及其相关子系统的性能,包括响应延迟、系统吞吐量、并发 处理能力、系统稳定性等技术指标。主要的优化手段有使用缓存加速数据读取,使用集群提高吞吐能力,使用异步消息加快请求响应及实现削峰,使用代码优化手段改善程序性能。运维人员更关注基础设施性能和资源利用率,如网络运营商的带宽能力、服务器硬件的配置、数据中心网络架构、服务器和网络带宽的资源利用率等。

性能测试指标

不同视角下有不同的性能标准,不同的标准有不同的性能测试指标,从开发和测试人员的视角,网站性能测试的主要指标有响应时间、并发数、吞吐量、性能计数器等。

  • 响应时间。指应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间。响应 时间是系统最重要的性能指标,直观地反映了系统的“快慢”。测试程序通过模拟应用程序,记录收到响应和发出请求之间的时间差来计算系统响应时间。但是记录及获取系统时间这个操作也需要花费一定的时间,如果测试目标操作本身需要花费的时间极少,比如几微秒,那么测试程序就无法测试得到系统的响应时间。实践中通常采用的办法是重复请求,比如一个请求操作重复执行一万次,测试一万次执行需要的总响应时间之和,然后除以一万,得到单次请求的响应时间。
  • 并发数。指系统能够同时处理请求的数目,这个数字也反映了系统的负载特性。对于网站而言,并发数即网站并发用户数,指同时提交请求的用户数目。现实中,经常看到某些网站,特别是电商类网站,市场推广人员兴致勃勃地打广告打折促销,用户兴致勃勃地去抢购,结果活动刚一开始,就因为并发用户数超过网站最大负载而响应缓慢,急性子 的用户不停刷新浏览器,导致系统并发数更高。
  • 吞吐量。指单位时间内系统处理的请求数量,体现系统的整体处理能力。对于网站,可以用“请求数/秒” 或是“页面数/秒”来衡量,也可以用“访问人数/天”或是“处理的业务数/小时”等来衡量。TPS(每秒事务数)是吞吐量的一个常用量化指标,此外还有 HPS(每秒 HTTP 请求数)、QPS(每秒查询数)等。系统吞吐量和系统并发数,以及 响应时间的关系可以形象地理解为高速公路的通行状况:吞吐量是每天通过收费站的车辆数目(可以换算成收费站收取的高速费),并发数是高速公路上的正在行驶的车辆数目,响应时间是车速。车辆很少时,车速很快,但是收到的高速费也相应较少;随着高速公路上车辆数目的增多,车速略受影响,但是收到的高速费增加很快;随着车辆的继续增加,车速变得 越来越慢,高速公路越来越堵,收费不增反降;如果车流量继续增加,超过某个极限后,任何偶然因素都会导致高速全部瘫痪,车走不动,费当然也收不着,而高速公路成了停车场( 资源耗尽)。
  • 性能计数器是描述服务器或操作系统性能的一些数据指标。包括System Load、对象与线程数、内存使用、CPU使用、磁盘与网络 I/O 等指标。这些指标也是系统监控的重要参数,对这些指标设置报警阈值,当监控系统发现性能计数器超过阈值时,就向运维和开发人员报警,及时发现处理系统异常。

性能测试方法

性能测试是一个总称,具体可细分为性能测试、负载测试、压力测试、稳定性测试。

  • 性能测试是以系统设计初期规划的性能指标为预期目标,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到性能预期。
  • 负载测试是对系统不断地增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临界值, 如某种资源已经呈饱和状态,这时继续对系统施加压力,系统的处理能力不但不能提高,反而会下降。
  • 压力测试是超过安全负载的情况下,对系统继续施加压力,直到系统崩溃或不能再处理任何请求,以此获得系统最大压力承受能力。
  • 稳定性测试是被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定。在不同生产环境、不同时间点的请求压力是不均匀的,呈波浪特性, 因此为了更好地模拟生产环境,稳定性测试也应不均匀地对系统施加压力。