大型网站架构

一. 大型网站架构演化

1.1 大型网站架构特点

  1. 高并发、大流量
  2. 高可用
  3. 海量数据:需要存储、管理海量数据,需要使用大量服务器。
  4. 用户分布广泛,网络情况复杂
  5. 安全环境恶劣:由于互联网开放性,使得网站容易受到攻击。
  6. 需求快速变更,发布频繁
  7. 渐进式发展

1.2 大型网站架构演化过程

  1. 初始阶段的网站架构: LAMP
  2. 应用服务和数据服务分离:用户越来越多导致存储空间不足,整个网站使用三台服务器,应用服务器、文件服务器和数据库服务器。
  3. 使用缓存改善网站性能:80%的业务访问集中在20%的数据上。可以把这一小部分数据缓存在内存中。缓存分为两种:
    • 本地缓存:速度快,但受服务器内存限制,其缓存数据量有限。
    • 缓存在专门分布式服务器的远程缓存。
  4. 使用应用服务器集群改善网站的并发处理能力: 使用集群是网站解决高并发、海量数据问题常用的手段。增加服务器分担原来服务器的访问和存储压力。需要使用负载均衡来调度集群中的服务器,使服务压力均衡的分配到各个机器。
  5. 数据库读写分离:在网站用户量达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。 目前大部分主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。写数据时访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库,这样当应用读数据的时候,可以通过从数据库获取数据
  6. 使用反向代理和CDN加速网站响应:CDN和反向代理基本原理都是缓存,一方面加快数据访问速度,另一方面也减轻了后端服务器的负载压力。两者的区别是:
    • CDN部署在网络提供商的机房,使用户在请求网站时,可以从距离自己最近的网络提供商机房获取数据。
    • 反向代理则部署在网站的中心机房,用户访问时首先访问服务器的反向代理,如果反向代理服务器中缓存了用户请求的资源,则直接返回给用户。
  7. 使用分布式文件系统和分布式数据库系统:采用业务分库手段将不同业务的数据库部署在不同的物理服务器上。 可以进行垂直拆分和水平拆分。
  8. 使用NoSQL和搜索引擎:非关系数据库是对可伸缩的分布式特性具有更好的支持。应用服务器则通过一个统一数据库访问模块访问各种数据,减轻应用程序管理的诸多数据源麻烦。
  9. 业务拆分: 将一个网站拆分成许多不同的应用,每个应用独立部署。应用之间通过一个超链接建立关系。垂直拆分,将不相干的服务拆分出来。
  10. 分布式服务:水平拆分,将多个业务中的公共业务服务提取出来、独立部署。分布式服务通过调用共用业务服务完成具体业务操作。

1.3 大型网站架构演化的价值观

  1. 大型网站架构技术的核心价值是随着网站所需灵活应对
  2. 驱动大型网站技术发展的主要力量是网站的业务发展

1.4 网站架构的误区

  1. 一味追求大公司的解决方案
  2. 为了技术而技术
  3. 企图用技术解决所有问题

二. 大型网站架构模式

每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你能一次又一次地使用该方案而不必做重复工作

2.1 网站架构模式

常用模式有:

  • 分层:将系统在横向维度上切分成几个部分,每个部分负责一部分相对比较单一的职责,然后通过上层对下层的依赖和调用组成一个完整系统。
  • 分割:按纵向方向对软件进行切分,将不同的功能和服务分割开来,包装成高内聚低耦合的模块单元,这些单元或模块可以独立部署
  • 分布式:将分层和分割后的模块进行分布式部署,即将不同模块部署在不同的服务器上,通过远程调用协调工作
  • 集群:多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务。
  • 缓存: 缓存是将数据存放在距离计算最近的位置以加快处理速度、同时减轻后端应用和数据存储的负载压力.

1. 分层

将系统在横向维度上切分成几个部分,每个部分负责一部分相对比较单一的职责,然后通过上层对下层的依赖和调用组成一个完整系统。

大型网站将网站系统分为:

  • 应用层:负责具体业务和视图展示,如网站首页及搜索输入和结果展示。
  • 服务层:为应用层提供服务支持,如用户管理服务、购物车服务等。
  • 数据库:提供数据存储访问服务,如数据库、缓存、文件、搜索引擎等。

分层好处:

  • 便于分工合作开发和维护
  • 各层之间有一定的独立性,只要维持调用接口不变,各层可以根据具体问题独立演化发展而不需要其他层必须做出相应调整。

挑战:

  • 必须合理规划层次边界和接口,在开发中严格遵循分层架构的约束,禁止跨层次的调用(应用层直接调用数据库)及逆向调用(数据库层调用服务层,或者服务层调用应用层)。

分层结构内部还可以继续分层,如应用层可以分为视图层和业务逻辑层。在物理部署上,三层结构可以部署在同一个物理机器上,但随着业务发展必须对分层的模块隔离部署

2. 分割

分割按纵向方向对软件进行切分,将不同的功能和服务分割开来,包装成高内聚低耦合的模块单元,这些单元或模块可以独立部署。存在的好处有:

  • 助于软件的开发和维护
  • 便于不同模块的分布式部署,提高网站并发处理能力和功能扩展能力
  • 可以根据不同模块的特点对不同模块进行优化,提高各模块性能

3. 分布式

对于大型网站来说,分层和分割的一个主要目的是为了切分后的模块便于分布式部署,即将不同模块部署在不同的服务器上,通过远程调用协调工作。

分布式在解决网站高并发问题的同时也带来其他问题:

  • 分布式意味着服务调用必须通过网络,这样可能对性能造成比较严重的影响。
  • 服务器越多,服务器的宕机概率也就越大。一台机器的宕机造成的服务不可用可能会导致很多应用不可访问,网站可用性降低
  • 数据在分布式环境中保持数据一致性也非常困难,分布式事务也难以保证,这对网站业务正确性和业务流程有可能造成很大影响。
  • 分布式还导致网站依赖错综复杂,开发管理维护困难

分布式方案有几种:

  • 分布式应用和服务: 将分层和分割后的应用和服务模块化分布式部署,除了改善网站性能和并发性、加快开发和发布速度、减少数据库连接资源消耗;还可以使用复用共同的服务,便于业务功能扩展。
  • 分布式静态资源: 将网站的静态资源如CSS、JS等独立分布式部署,采用独立的域名,即动静分离。静态资源分布式部署可以减轻应用服务器的负载压力;通过使用独立域名加快浏览器并发加载的速度。也便于卡法维护,使不同技术工种术业有专攻。
  • 分布式数据和存储
  • 分布式计算: 搜索引擎索引构建、数据仓库等大规模计算普遍使用Hadoop及MapReduce分布式计算框架,特点是移动计算而不是移动数据,将计算程序分发到数据所在的位置及加速计算和分布式计算。

4. 集群

集群即多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务。一个应用由多台服务器提供,当某台服务器发生故障时,负载均衡设备或系统的失效转移机制会将请求转发到集群中其他服务器上,使服务器故障不影响用户使用。

5. 缓存

缓存是将数据存放在距离计算最近的位置以加快处理速度、同时减轻后端应用和数据存储的负载压力。数据缓存有两个前提:

  • 数据访问热点不均衡,某些数据会被频繁的访问。
  • 数据在某个时间段内有效,不会很快过期。

一般缓存包含多个方面:

  • CDN: 即内容分发网络,部署在距离终端用户最近的网络服务商,用户网络请求总是先到达他的网络服务商哪里,这里缓存网站的一些静态资源可以以最快速度返回给用户。
  • 反向代理: 反向代理属于网站前端架构的一部分,部署在网站的前端。当用户请求到达网站数据库中心时,最先访问反向代理服务器,这里缓存网站的静态资源,如果存在资源则返回给用户无需再请求服务器。
  • 本地缓存: 在应用服务器本地缓存着热点数据。
  • 分布式缓存: 将数据缓存在一个专门的分布式缓存集群中,应用程序通过网络通讯访问缓存数据。

6. 异步

计算机开发的一个重要目标和驱动力是降低软件耦合性。 系统解耦的手段除了分层、分割、分布等还有一个重要手段是异步。

单一服务通过多线程共享内存队列的方式实现异步。在分布式系统中,多个服务器集群通过分布式消息队列实现异步,分布式消息队列可以看作内存队列的分布式部署(如消息队列kafka)。

异步消息队列有以下特性:

  • 提高系统可用性。消费者如果挂了,数据会在消息队列堆积,生产者服务可以继续处理业务逻辑,系统整体表现无故障。消费者恢复后继续处理消息队列数据。
  • 加快网站响应速度。生产者不用同步等待消费者消费结果,生产者处理完业务请求后将数据写入消息队列就可以返回,响应延迟减少。
  • 消除并发访问高峰(削峰)。使用消息队列将突然增加的访问请求数据写入消息队列中,消费者服务器还是可以继续依次处理,不会对整个网站负载造成太大压力。

7. 冗余

想要保证在服务器宕机的情况下网站依然可以继续服务,不丢失数据,就需要一定程度的服务器冗余运行,数据冗余备份,这样当某台服务器宕机时,可以将其上的服务和数据访问转移到其他机器上。

数据库除了定期备份、存档保存,实现冷备份外,为了保证在线业务高可用,还需要对数据库进行主从分离,实现同步热备份

8. 自动化

在无人值守的情况下网站可以正常运行,一切都可以自动化是网站的理想状态。包含:发布过程自动化、自动化代码管理、自动化测试、自动化安全检查、自动化部署、自动化监控、自动化抱紧、自动化失效转移、自动化失效恢复、自动化降级、自动化分配资源。

9. 安全

可以从以下几个方面考虑:密码、手机校验码、通讯加密、敏感信息过滤、风险控制。

三. 大型网站核心架构要素

架构是最高层次的规划,难以改变的决定。这个规划和决定奠定了事物未来发展的方向和最终的蓝图。

软件架构是有关软件整体结构和组件的抽象描述,用于指导大型软件系统各个方面的设计。系统的各个重要组成部分及其关系构成了系统的架构,这些组成部分可以是具体的功能模块,也可以是非功能模块的设计与决策,他们相互关联组成一个整体,共同构成了软件系统的架构。

一般除了当前系统功能需求外, 软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性5个要素。

3.1 性能

性能是网站的处理效率、通过一系列指标去衡量,重要的有响应时间、TPS、并发数、吞吐量等。

优化可以从以下几个方面进行:

  1. 浏览器端:浏览器缓存、使用页面压缩、CSS/JS合并减少HTTP次数、合理布局页面、减少Cookie传输等手段。
  2. 使用CDN:将网站静态内容分发至离用户最近的网络服务商机房。是用户通过最短访问路径获取数据。
  3. 部署反向代理:通过反向代理缓存热点文件、加快请求响应速度,减轻应用服务器负载压力。
  4. 应用服务器本地缓存和分布式缓存:通过缓存热点数据处理用户请求,加快请求处理过程,减轻数据库负载压力。
  5. 异步操作: 将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户。
  6. 集群: 在高并发请求的情况下,使用负载均衡技术为一个应用构建一个由多台服务器组成的服务器集群,将并发访问请求分发到多台服务器上处理,避免单一服务器因负载压力过大而响应缓慢,使用户请求具有更好的响应延迟特性。
  7. 代码层面:使用多线程、改善内存管理等手段优化性能。
  8. 数据库端:使用索引、缓存、SQL优化等性能优化手段。

3.2 可用性

可用性:当服务器宕机的时候,服务或应用依然可用。主要衡量标准一个系统设计是否满足高可用的目标,就是假设系统中任何一台或多台服务器宕机时,已经出现各种不可预期的问题时,系统整体是否依然可用。

高可用的主要手段是冗余

  • 应用服务器通过负载均衡设备组合一个集群共同对外提供服务,任何一台服务器宕机只需把请求切换到其他服务器就可以实现应用的高可用,但前提是应用服务器上不能保持请求的会话信息
  • 存储服务器进行实时备份,当服务器宕机时需要将数据访问转移到可用的服务器上,并进行数据恢复以保证继续有服务宕机的时候数据依然可用。

3.3 伸缩性

伸缩性是指通过不断向集群加入服务器的手段来环节不断上升的用户并发访问压力和不断增长的数据存储需求。主要衡量标准是:

  • 是否可用用多台服务器构建集群
  • 是否容易向集群添加新的服务器
  • 加入新的服务器后是否可以提供和原来的服务器无差别的服务
  • 集群中可容纳的总服务器数量是否有限制

主要策略有:

  • 应用服务器:只要服务器不保存数据,所有服务器都是对等的,通过使用合适的负载均衡设备就可以向集群中不断加入服务器。
  • 缓存服务器集群: 加入新服务器可能导致缓存路由失效,进而导致集群中大部分缓存数据都无法访问,可能导致整个网站崩溃。需要通过改进缓存路由算法保证数据的可访问性,如一致性hash算法。
  • 关系数据库:关系数据库虽然支持数据复制,主从热备等机制,但是很难做到大规模集群的可伸缩线。因此关系数据库的集群伸缩性必须在数据库之外实现。通过路由分区等手段部署多个数据库的服务器组成一个集群。
  • NoSQL: 大部分NoSQL先天就是为海量数据而生,在较少运维参与的情况下实现集群规模的线性伸缩。

3.4 扩展性

不同于其他架构要素主要关注非功能性需求,网站的扩展性架构直接关注网站的功能需求。网站扩展性的目的是如何设计网站架构使得其能够快速响应需求变化。主要衡量标准是:

  • 在网站增加新业务产品时,是否可以实现对现有产品透明无影响,不需要任何改动或者很少改动既有业务功能就可以上线新产品。
  • 不同产品之间是否很少耦合,一个产品改动对其他产品无影响,其他产品和功能不需要受牵连进行改动。

扩展性架构的主要手段是事件驱动分布式服务

  • 事件驱动架构在网站通常利用消息队列实现。将消息生成者和消费者解耦,可以透明地增加新的消息生产者和消费者。
  • 分布式服务则是将业务和可复用服务分离开,通过分布式服务框架调用。新增产品可以通过调用可复用的服务实现自身的业务逻辑,而对现有产品没有任何影响。可复用服务升级变更时,也可以通过提供多版本服务对应用实现透明升级,不需要强制应用同步变更。

3.5 安全性

网络安全主要是保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取。衡量标准是针对现存和潜在的各种攻击和窃密手段,是否有可能的应对策略。

四. 瞬时响应: 网站的高性能架构

4.1 性能指标

  1. 响应时间:指应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间。
    • 实践中一般采用平均响应时间,比如重复1万次,求得平均响应时间。
  2. 并发数: 系统能够同时处理请求的数据,也反映了系统的负载特性。
    • 通过多线程模拟并发用户来测试系统的并发处理能力,两次请求之间加入一个随机等待时间。
  3. 吞吐量: 指单位时间内系统处理的请求数量,提现系统的整体处理能力。如:“请求数/秒”、“页面数/秒”。
    • TPS: 每秒事务数
    • HPS: 每秒HTTP请求数
    • QPS: 每秒查询数
  4. 性能测试器: 描述服务器或操作系统性能的一些数据指标,包括System Load、对象与线程数、内存使用、CPU使用、磁盘和网络I/O等指标。
  • System load即系统负载:当前正在被CPU执行和等待CPU执行的进程数据之和,反映系统忙闲程度的重要指标。可通过top命令查看。

4.2 性能测试方法

性能测试反应系统在实际生产环境中使用时,随着用户并发访问数量的增加,系统的处理能力。与性能对应的是用户访问的等待时间(系统响应时间)。

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

4.3 web前端性能优化

  1. 浏览器访问优化
    • 使用浏览器缓存: 在浏览器缓存服务器更新频率很大的静态文件,如CSS/JS/LOGO等。在更新静态资源时,采用逐量更新。
    • 减少HTTP请求: 主要手段是合并css、js等,减少对服务器访问次数。
    • 启动压缩: 对css/js等资源进行压缩,提供传输效率。
    • 合理布局页面: css放在页面最上面,JS放在最下面。还可以采用bigPipe将页面分割为多块并行加载渲染。
    • 减少Cookie传输: 避免静态资源请求时发送Cookie,减少Cookie传输次数。
  2. CDN加速:本质上是一个缓存
    • 将网站静态内容缓存在离用户最近的网络服务商机房,使用户通过最短访问路径访问资源,可最快速度获取数据。
  3. 反向代理
    • 缓存热点静态文件资源、加快请求响应速度、减轻服务器负载压力。
    • 作为应用服务器的一个安全屏障
    • 实现负载均衡,通过负载均衡构建应用集群提高系统总体处理能力,进而改善网站高并发下的性能。

4.4 应用服务器性能优化

应用服务器是处理网站业务的服务器,其主要优化手段有缓存、集群、异步等。

1. 分布式缓存

缓存指将数据存储在相对较高访问速度的存储介质中,以供系统处理,缓存的本质是一个内存Hash表,读写时间复杂度为O(1)。缓存有以下优点:

  • 缓存访问速度快,可以减少数据访问时间
  • 缓存还起到减少计算的作用。缓存的数据是经过计算处理得到,那么被缓存的数据无需重复计算即可直接使用。
  • 减少数据库压力,一些高频和热点数据直接从缓存读取,而无需从数据库读取,可以给数据库分担压力。

缓存主要用来存储那些读写比很高、很少变化的数据。应当合理使用缓存:

  • 避免存储频繁修改的数据:数据的读写比例最好要大于2:1。
  • 避免存储没有热点的数据:不能讲所有数据都缓存,应该存储那些热点数据。
  • 数据不一致与脏读: 对缓存设置一个失效时间,一旦超过失效时间就要冲数据库重新加载。 数据更新时使用两种策略,一种是延迟加载或过期失效(存在数据不一致问题)、一种是立即更新缓存(带来系统开销和事务一致性问题)
  • 缓存可用性: 当缓存服务崩溃了,导致所有访问请求直接访问数据库,造成数据库压力太大而宕机,这种故障称为缓存雪崩。常用解决方案:
    • 实践中应该采用热备服务器,当某缓存服务器宕机可从起备服务器读取,避免缓存雪崩问题。
    • 将缓存失效时间分散开(因过期时间)
  • 缓存预热: 新启动的缓存系统没有任何数据,可以在缓存系统启动时把热点数据加载好。或者在启动时将一些不变的数据全部缓存预热。
  • 缓存穿透: 因为不恰当的业务或者外部恶意攻击持续高并发地请求某些不存在的数据,由于缓存没有保存,所有请求都会落在数据库上,对数据库造成很大的压力,甚至崩溃。处理方式:
    • 可以将不存在的数据缓存,其value是null, 并设置较短的过期时间。
    • 将存在的数据放在一个BitSet或布隆过滤器中,如果不在这个范围直接过滤。
    • 将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

缓存雪崩本质是一些访问请求不经过Redis而突然全部请求到数据库,导致数据库压力陡增,造成压力太大而宕机。 一般有两种原因导致:

  1. 缓存服务崩溃或不存在备库,某台缓存服务器挂了。----解决方案是冗余、热备服务器。
  2. 很多缓存数据都设置了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。 -----解决方案:将缓存失效时间分散开(因过期时间)

分布式缓存架构分为两种:

  • 以Jboss Cache为代表的需要更新同步的分布式缓存。Jboss Cache通常将应用程序和缓存部署在同一台服务器上,可快速获取数据,但这种方式缓存数据量受限单一服务器内存空间。
  • 以memcached为代表的不互相通信的分布式缓存。Memcached采用集中式的缓存集群管理,缓存和应用部署分离,缓存服务器之间不互相通信(提高可伸缩性)。应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据。

远程通信设计需要考虑两个元素:

  • 通信协议: 选择TCP还是UDP、或者HTTP。
  • 通信序列化协议: 数据传输的两端,必须使用彼此可识别的数据序列化方式才能使通信得以完成。如XML、JSON、Protobuffer等。

Memcached采用TCP协议,其序列化协议则是一套基于文本的自定义协议,以命令关键字开头,后面是一组命令字操作数。

2. 异步操作

使用消息队列调用异步化,可改善网站的扩展性,还可以改善网站的性能。

  • 消息队列提高生产者响应速度:写入消息队列后可立即返回。
  • 消息队列具有很好的削峰作用:通过异步处理、将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。
  • 生成者与消费者的解耦:可避免生成者与消费者的强耦合。
  • 可扩展: 可以增加消费者订阅消息来完成新的业务逻辑扩展,无需改动原有逻辑。
  • 可伸缩性: 异步消费队列解耦生产者和消费者,消费者之间是对等关系,可以通过合理增加消费者提高消息处理性能。

3. 使用集群

使用负载均衡技术为一个应用构建一个由多台服务器组成的服务器集群,将并发访问请求分发到多台服务器上处理,避免单一服务器因负载压力过大而响应缓慢,使用户请求具有更好的响应延迟特性。

4. 代码优化

合理优化业务代码,可以很好地改善网站性能。

  1. 使用多线程,提高并行处理能力。
  2. 资源复用:要尽量减少那些开销很大的资源的创建和消费,提高响应速度和减少资源开销。资源复用主要两种模式:单例(数据源、Dao等)对象池(数据库连接池、线程池、通信连接池等)
  3. 数据结构和算法:使用合理的数据结构和算法有利于提高代码性能。
  4. 垃圾回收: 通过程序调优、参数调优来提高垃圾回收性能。

5. 存储优化

  1. 机械键盘: 通过马达驱动头臂带动磁头到指定的磁盘位置访问数据。数据连续访问和随机访问移动次数相差巨大,性能表现也比较差。

  2. 固态硬盘: 没有机械装置,存储在在可记忆的硅晶体上,可以像内存一样快速随机访问。

  3. B+树: 为了改善数据访问特性,加快速度检索速度,需要保证数据在不断更新、插入、删除后依然有序,传统的做法采用+树。

  4. LSM: 可以看作是一个N阶合并树。数据写操作(包括插入、修改、删除)都在内存进行,并且创建一个新记录。(修改会记录新的数据值,删除会记录一个删除标志),这些数据在内存中仍然是一颗排序树,当数据量超过设定的内存阈值后,会将这棵排序树和磁盘最新的排序树合并。当这棵排序树的数据量超过设定阈值后和磁盘上的下一级排序树合并。合并过程中会使用最新更新的数据覆盖旧的数据。在需要进行读操作时,总是从内存中的排序树开始搜索。如果没有找到,就从磁盘上的排序树顺序查找。

  5. RAID

    • RAID0: 数据从内存缓冲区写入磁盘时,根据磁盘数量降数据分为N份,这些数据同时并发写入N块磁盘。
    • RAID1: 将一份数据同时写入两块磁盘,任何一块损坏都不会导致数据丢失,具有极高的可靠性。
    • RAID10: 结合RAID0和RAID1两种方案,将所有磁盘平均分为两份,数据同时在两份磁盘写入,相当于RAID1。在每一份磁盘里面的将数据分为N/2份并行写入N/2个磁盘中,提供性能。类似kafka的消费组和消费者的设计理念。
    • RAID3: 将数据写入N-1份,并发写入N-1块磁盘。并在第N块磁盘记录校验值用于恢复,容易导致第N块磁盘损坏。
    • RAID5: 和RAID3很类似,但校验数据是采用螺旋式写入所有磁盘中,避免频繁写坏一块磁盘。
    • RAID6: 和RAID5类似,但数据只写入N-2块磁盘,并螺旋式地在两块磁盘中写入校验信息。
  6. HDFS: 按块(block)为基本单位存储,一个块数据三个备份。

五. 高可用架构

5.1 高可用架构

可用性度量:4个9

网站不可用时间(故障时间)= 故障修复时间点 - 故障发现(报告)时间点 网站年度可用指标 = (1 - 网站不可用时间/年度总时间) * 100%

  • 2个9基本可用,不可用时间小于88小时
  • 3个9较高可用,不可用时间小于9小时
  • 4个9具有自动恢复能力的高可用,不可用时间小于53分钟。
  • 5个9极高可用性,不可用时间小于5分钟。

高可用架构设计的目的就是抱着服务器硬件故障时服务器依然可用、数据依然保存并能够被访问。主要的手段是数据和服务的冗余备份及失效转移

  • 位于应用层的服务器:通过负载均衡设备将一组服务器组成一个集群共同对外提供服务,当负载均衡设备通过心跳检测手段检测应用服务器不可用时,将将其从集群列表剔除。应用的高可用架构设计是基于服务的无状态特性,所谓无状态是服务器不保存业务的上下文信息,多个服务器之间完全对等。
  • 位于服务层的服务器:通过集群实现高可用,通过分布式服务调用框架访问并在客户端程序中实现软件负载均衡(如dubbo),并通过注册中心对提供服务的服务器进行心跳检测。
  • 位于数据层的服务器:数据写入时进行数据同步复制,将数据写入多台实现冗余备份

1 高可用应用

集群中的session管理方式:

  • session复制:在集群中的几台服务器之间同步session对象--占用服务器和网络的大量资源。
  • session绑定:利用负载均衡的源地址Hash算法实现,将源于同一个IP请求分发到同一台服务器上。----不符合高可用需求
  • 利用cookie记录Session: 将session记录存放在客户端,每次请求的时候将session发送给服务器,服务器修改完成后发给客户端。缺点是:
    • 受cookie大小限制
    • 每次需要传输Cookie,影响性能
  • session服务器:利用独立部署的session服务器统一管理session, 解决应用服务器的状态分离。简单方式:分布式缓存、数据库等。

2 高可用服务

也是基于服务的无状态,还有几点高可用服务策略:

  • 分级管理:核心应用和服务区分对待,应用部署进行必要隔离。
  • 超时设置:如果用户请求长时间得不到响应,会占用应用程序资源,不利于及时将访问请求转移到正常服务器上。
  • 异步调用:通过消息队列异步方式完成,避免一个服务失败导致整个应用请求失败的情况。
  • 服务降级拒绝服务(拒绝低优先级应用的调用,减少服务并发数)和关闭功能(关闭不重要的功能,节约系统开销)。
  • 幂等性控制:保证服务重复调用和调用一次产生的结果相同。

3 高可用数据

高可用数据有以下几个层面的含义:

  • 数据持久性:保证数据可持久存储,在各种情况下都不会出现数据丢失的问题。
  • 数据可访问性:在多份数据副本分别存放在不同存储设备的情况下,如果一个数据存储设备损坏,就需要将数据访问切换到另一个数据存储设备上。
  • 数据一致性:多个副本数据保持一致。

保证数据存储的高可用手段主要有数据备份失效转移机制

  • 数据备份分为冷备份(定期备份)热备份(主从复制),数据热备的方式存在两种异步备份方式同步备份方式
    • 异步备份:写入一份数据后,系统将异步向其他副本写入数据。
    • 同步备份:多份数据副本的写入操作同步完成,为了提供性能应用程序客户端并发向多个存储服务同时写入数据,然后等待所有存储服务器都返回操作成功的响应后,在通知应用程序写操作成功。
  • 失效转移操作由三个部分组成:
    • 失效确认:系统确认一台服务器是否宕机,常用手段有心跳检测应用程序失败报告
    • 访问转移:确认某台数据存储服务器宕机后,需要将数据读写访问重新路由到其他服务器上。
    • 数据恢复:将宕机服务器进行恢复,需要从健康服务器复制数据,将数据副本恢复到设定值。

CAP原理:系统无法同时满足数据一致性(Consistency)、数据可用性(Availability)和分区耐受性(Partition Tolerance,系统具有跨网络分区的伸缩性)

数据一致性分为如下几点:

  • 数据强一致:各个副本数据在物理上总是保持一致。
  • 数据用户一致:各个副本可能不一致,但终端用户访问时通过纠错和校验机制,确定一个一致的且正确的数据返回给用户。
  • 数据最终一致:各副本不一致,通过系统一段时间的自我修复和修正,数据最终会打到一致。

5.2 软件质量保证

网站发布

  1. 网站发布
  2. 自动化测试
  3. 预发布验证:预发布服务器是一种特殊的服务器,它和线上的正式服务器唯一的不同就是没有配置在负载均衡服务器上,外部用户无法访问。
  4. 代码控制:主干开发分支发布和分支开发主干发布。
  5. 自动化发布:采用火车模型,将每个应用的发布过程看做一次火车旅程,火车定点运行,期间有若干站点,每一站都进行例行检查,不通过的项目下车,剩下的项目继续坐火车旅行,直到终点。
  6. 灰度发布:将集群分为若干部分,每天只发布一部分服务器,观察运行稳定没有故障,第二天继续发布一部分服务器,如果有问题则回滚。

运行监控

  1. 日志采集
    • 用户行为日志
      • 服务器端日志收集
      • 客户端浏览器日志收集
    • 服务器性能监控
    • 运行数据报告
  2. 监控管理
    • 系统报警
    • 失效转移:
    • 自动优雅降级:主动关闭部分功能,释放部分系统资源,保证网站核心功能正常访问的一个手段。

六. 网站的伸缩性架构

所谓的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或缩小网站的服务处理能力。

网站伸缩性设计可分为两类:

  • 根据功能进行物理分离实现伸缩----分布式
    • 纵向分离(分层):将业务处理流程上不同的部分分离部署,实现系统伸缩性。
    • 横向分离: 将不同业务模块分离部署,实现系统伸缩性。
  • 单一功能通过集群实现伸缩---集群
    • 将相同服务部署在多台服务器上构成一个集群整体对外提供服务。

1. 应用服务器集群的伸缩性设计

应用服务器应该设置为无状态,任何一台服务器的处理结果都是相同的。这样用户请求按照某种规则分发到集群的不同服务器上,可构成一个应用服务器集群。常用的负载均衡设备有:

  • Http 重定向负载均衡:根据用户的HTTP请求计算一台真实的Web服务器地址,并将该Web服务器地址写入HTTP重定向响应中(响应302)返回浏览器,浏览器重新发起请求到实际物理服务器。
    • 缺点:
      • 浏览器需要两次请求服务器才能完成一次访问,性能较差。
      • 重定向服务器自身的处理能力有可能成为瓶颈,整个集群伸缩性有限。
  • DNS域名解析负载均衡:每次根据负载均衡算法计算一个不同的IP地址返回给浏览器,浏览器根据这个IP地址访问真实物理地址。
    • 优点:
      • 将负载均衡工作交给DNS,省掉了网站管理维护负载均衡服务器的麻烦。
      • 同时还支持基于地理位置的域名解析,即将域名解析成距离用户地理最近的一个服务器地址,这样可以加快用户访问速度,改善性能。
    • 缺点:采用多级解析,域名解析更新后不能立即生效,到时用户访问失败
  • 反向代理负载均衡: 方向代理服务器处于web服务器前面,浏览器请求的地址是方向代理服务器的地址,方向代理收到请求后,根据负载均衡算法计算到一台真实物理服务器地址。
    • 缺点:反向代理服务器是所有请求和响应的中转站,其性能可能会成为瓶颈。
  • IP负载均衡:用户请求包到达负载均衡服务器后,获取网络数据包,根据负载均衡算法计算得到一台真实WEB服务区地址,然后将数据局目的IP修改为该地址。响应地址到达负载均衡服务器后,负载均衡服务器再将数据包源地址修改为自身的IP地址。
  • 数据链路层均衡负载: 数据链路层负载均衡是在通讯协议的数据链路层修改mac地址进行负载均衡。这种传输方式成为三角传输模式,只修改mac地址,不修改数据包的原地址和目的地址而达到转发目的。目前大型网站使用的比较多,最好的开源产品是LVS(Linux Virtual Server)

负载均衡算法:

  • 轮询(Round Robin, RR)
  • 加权轮询(Weighted Round Robin, WRR): 按照配置的权重将请求分发到每个服务器。
  • 随机(Random): 也可以使用加权随机算法。
  • 最少连接(Least Connections): 记录每个应用服务器正在处理的连接数,将新到的请求分发到最少连接的服务器上。
  • 源地址散列: 根据请求来源的IP地址进行Hash计算,得到应用服务器,这样来自同一个IP地址的请求总在同一个服务器上处理。
  • 一致性Hash算法

2. 分布式缓存集群的伸缩性设计

和应用服务器集群不同,分布式缓存服务器集群中不同服务器缓存的数据各不相同,是不对等的,缓存访问请求不可以在缓存服务器集群中的任意一台处理,必须找到缓存有需要数据的服务器,才能访问。这个特点严重制约了分布式缓存集群的伸缩性设计。

分布式缓存集群伸缩性设计的最主要目标:新上线的缓存服务器对真个分布式缓存集群影响最小,即新加入缓存服务器后应使得整个服务器集群已经缓存的数据尽可能被访问到。

  • Mecheched采用一致性hash算法
  • Redis采用reshard和rebalance

3. 数据存储服务器集群的伸缩性设计

关系数据库可以使用伸缩性主要有两种:

  1. 主从读写分离
  2. 数据库分库:将不同业务数据库表部署在不同的数据库集群上,可以使用分布式关系数据库访问代理Cobar

Cobar伸缩性:

  • Cobar服务器集群的伸缩性:因为Cobar是无状态的应用服务器,因此可以使用集群伸缩来实现负载均衡。
  • MySql服务器集群的伸缩:采用一致性Hash进行数据迁移,迁移是以schema为单位

NoSql集群放弃了关系数据库以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID),强化了高可用性可伸缩性

七.网站的可扩展性架构

扩展性是一种开发封闭的设计原则,指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。

构造可扩展的网站架构有两种方式:

  1. 基于事件驱动架构----利用分布式消息队列降低耦合性
  2. 基于分布集群架构----水平拆分和纵向拆分
    • 纵向拆分:将一个大应用拆分为多个小应用,各应用相对独立
    • 横向拆分: 将复用的业务拆处理啊,独立部署为分布式服务。

很多功能集中在一个模块中的问题:

  1. 编译、部署困难----慢
  2. 代码分支管理困难----多人开发、冲突多
  3. 数据库连接耗尽
  4. 新增业务困难---修改一行对其他影响都很大

分布式服务框架还需支持如下特性:

  1. 负载均衡
  2. 失效转移
  3. 高效的远程通信
  4. 整合异构系统
  5. 对应用最小侵入
  6. 版本管理
  7. 实时监控

八. 网站的安全架构

常见攻击手段:

  • XSS攻击:跨站点脚本攻击,通过篡改页面,注入恶意HTML脚本,在用户浏览器页面时,控制用户浏览器进行恶意操作的一种攻击方式。
  • 注入攻击:如SQL注入和OS注入攻击
  • CSRF:跨站点请求伪造,攻击者通过跨站请求,以合法用户身份进行非法操作。其核心是利用浏览器Cookie或服务器Session策略盗取用户身份。
  • 其他攻击和漏洞
    • Error Code: 错误回显,应该避免
    • HTML注释
    • 文件上传:设置上传文件白名单,只允许上传可靠的文件类型。
    • 路径遍历:利用请求的URL中使用相对路径,遍历系统未开放的目录和文件。

防御手段:

  • 信息加密和密钥安全管理
    • 单向散列加密: 通过对不同输入长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出进行计算从而获得输入信息。---可以用于密码保护,密码校验等。常用的有MD5、SHA等。
    • 对称加密:加密和解密使用的秘钥是同一个秘钥。---通常用在信息需要安全交换或存储的场合。
      • 优点:算法简单、加密效率高,系统开销小。
      • 缺点:如果秘钥丢失,信息不安全。
    • 非对称加密
      • 使用不同的秘钥不是同一个秘钥,其中对外公布的称为公钥,只有所有知道的称为秘钥。用公钥加密的信息必须用私钥才能解开,反之用私钥加密的信息只有公钥才能解开。常见的算法是RSA。
    • 密钥安全
      • 把密钥和算法放在一个独立的服务器上,甚至做成一个专用的硬件设施。
      • 将加密算法放在应用系统中,密钥则放在独立服务器中,提高密钥的安全性。
  • 信息过滤和反垃圾
    • 文本匹配
    • 分类算法
    • 黑名单
  • 风险控制
    • 风险
      • 账户风险:包括账户被黑客盗用,恶意注册账号等情景
      • 买家风险:买家恶意下单占用库存进行不正当竞争。
      • 卖家风险:不良卖家进行恶意欺诈行为
      • 交易风险:信用卡盗刷,支付欺诈,洗钱。
    • 风控
      • 规则引擎
      • 统计模型

你可能感兴趣的:(架构,架构)