C++ 全栈知识体系C++ 全栈知识体系
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
  • 编程语言与技术

    • Effective C++: 改善程序与设计的55个具体做法

      • 第2章 - 构造/析构/赋值运算(一)
      • 第2章 - 构造/析构/赋值运算(二)
      • 第2章 - 构造/析构/赋值运算(三)
      • 第3章 - 资源管理
      • 第4章 - 设计与声明(一)
      • 第4章 - 设计与声明(二)
      • 第5章 - 实现(一)
      • 第5章 - 实现(二)
      • 第6章 - 继承与面向对象设计
      • 第7章 - 模板与泛型编程
    • 深度探索C++对象模型

      • 第1章 - 关于对象
      • 第2章 - 构造函数语意学
      • 第3章 - Data 语意学
    • STL源码剖析

      • 第1章 - STL概论和版本简介
      • 第2章 - 空间配置器
      • 第3章 - 迭代器(iterators)概念与traits编程技法(一)
      • 第3章 - 迭代器(iterators)概念与traits编程技法(二)
      • 第4章 - 序列式容器 vector
      • 第4章 - 序列式容器 list
      • 第4章 - 序列式容器 deque
      • 第4章 - 序列式容器 stack和queue
      • 第4章 - 序列式容器 heap
      • 第4章 - 序列式容器 priority_queue
      • 第4章 - 序列式容器 slist
      • 第5章 - 关联式容器 RB-tree
      • 第5章 - 关联式容器 set和map
      • 第5章 - 关联式容器 hashtable
      • 第6章 - 算法
      • 第6章 - 算法之set
      • 第7章 - 仿函数
      • 第8章 - 配接器
  • 系统与架构

    • 深入理解计算机系统

      • 第1章 - 计算机系统漫游
      • 第2章 - 信息的表示和处理
      • 第3章 - 程序的机器级表示
      • 第5章 - 优化程序性能
      • 第6章 - 存储器层次结构
      • 第7章 - 链接
      • 第8章 - 异常控制流
      • 第9章 - 虚拟内存
      • 第10章 - 系统级I/O
      • 第11章 - 网络编程
      • 第12章 - 并发编程
    • 大型网站技术架构——核心原理与案例分析

      • 第1章 - 大型网站架构演化
      • 第2章 - 大型网站架构模式
      • 第3章 - 大型网站核心架构要素
      • 第4章 - 瞬时响应:网站的高性能架构
      • 第5章 - 万无一失:网站的高可用架构
      • 第6章 - 永无止境:网站的伸缩性架构
      • 第7章 - 随需应变:网站的可扩展架构
      • 第8章 - 固若金汤:网站的安全架构
    • 从零开始学架构

      • 架构基础
      • 架构设计原则
      • 高性能架构
      • 高可用架构
    • 程序员的自我修养————链接、装载与库

      • 第1章 - 简介
      • 第2章 - 静态链路
      • 第3章 - 目标文件里有什么
      • 第4章 - 静态链接
      • 第7章 - 动态链接
      • 第8章 - 共享库版本
      • 第10章 - 内存
      • 第11章 - 运行库
      • 第12章 - 系统调用与API
      • 第13章 - 运行库实现
  • 软件开发实践

    • 重构改善既有代码的设计

      • 第1章 - 重构,第一个示例
      • 第2章 - 重构的原则
      • 第3章 - 代码的坏味道
      • 第5章 - 重构列表
      • 第6章 - 重新组织函数
      • 第7章 - 在对象之间搬移特性
      • 第8章 - 重新组织数据
      • 第9章 - 简化条件表达式
      • 第10章 - 简化函数调用
      • 第11章 - 处理概括关系
      • 第12章 - 设计之大型重构
    • 代码大全2

      • 第1章 - 欢迎进入软件构建的世界
      • 第2章 - 用隐喻来更充分地理解软件开发
      • 第3章 - 三思而后行: 前期准备
      • 第4章 - 关键的构建决策
      • 第5章 - 软件构建中的设计
    • Linux多线程服务端编程——使用muduo C++ 网络库

      • Buffer类的设计
      • 设计与实现
      • 定时器与TimerQueue
      • Protobuf网络传输和Protobuf编解码器与消息分发器
      • EventLoop类剖析
      • EventLoopThread和EventLoopThreadPool剖析
      • TCP网络库和核心类
      • Connector剖析
      • TcpClient剖析
      • 学习总结
      • timing wheel
      • 消息广播服务
      • 线程安全的对象生命期管理
  • 数据处理与应用设计

    • 数据密集型应用系统设计

      • 第1章 - 可靠、可扩展与可维护的应用系统
      • 第2章 - 数据模型与查询语言
      • 第3章 - 数据存储与检索
      • 第4章 - 数据编码与演化
      • 第5章 - 数据复制
      • 第6章 - 数据分区
      • 第7章 - 事务

第3章:大型网站核心架构要素

  • 性能
  • 可用性
  • 伸缩性
  • 扩展性
  • 安全性

关于什么是架构,一种比较通俗的说法是“最高层次的规划,难以改变的决定”,这些规划和决定奠定了事物未来发展的方向和最终的蓝图。

从这个意义上说,人生规划也是一种架构。选什么学校、学什么专业、进什么公司、找什么对象,过什么样的生活,都是自己人生的架构。

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

一般说来,除了当前的系统功能需求外,软件架构还需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素,架构设计过程中需要平衡这5个要素之间的关系 以实现需求和架构目标,也可以通过考察这些架构要素来衡量一个软件架构设计的优劣, 判断其是否满足期望。

性能

性能是网站的一个重要指标,除非是没得选择(比如只能到www.12306.cn这一个网 站上买火车票),否则用户无法忍受一个响应缓慢的网站。一个打开缓慢的网站会导致严 重的用户流失,很多时候网站性能问题是网站架构升级优化的触发器。可以说性能是网站架构设计的一个重要方面,任何软件架构设计方案都必须考虑可能会带来的性能问题。

也正是因为性能问题几乎无处不在,所以优化网站性能的手段也非常多,从用户浏览器到数据库,影响用户请求的所有环节都可以进行性能优化。

浏览器端:

  • 通过浏览器缓存、使用页面压缩、合理布局页面、减少Cookie传输等手段改善性能。

缓存:

  • 使用CDN,将网站静态内容分发至离用户最近的网络服务商机房,使用户通过最短访问路径获取数据。
  • 可以在网站机房部署反向代理服务器,缓存热点文件,加快 请求响应速度,减轻应用服务器负载压力。

应用服务器端:

  • 使用服务器本地缓存和分布式缓存,通过缓存在内存中的热点数据处理用户请求,加快请求处理过程,减轻数据库负载压力。
  • 通过异步操作将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户。
  • 将多台应用服务器组成一个集群共同对外服务,提高整体处理能力,改善性能。

代码层面:

  • 通过使用多线程、改善内存管理等手段优化性能。

在数据库服务器端,

  • 索引、缓存、SQL优化等性能优化。
  • NoSQL数据库通过优化数据模型、存储结构、伸缩特性等手段。

衡量网站性能有一系列指标,重要的有响应时间、TPS、系统性能计数器等,通过测试这些指标以确定系统设计是否达到目标。这些指标也是网站监控的重要参数,通过监 控这些指标可以分析系统瓶颈,预测网站容量,并对异常指标进行报警,保障系统可用。

对于网站而言,性能符合预期仅仅是必要条件,因为无法预知网站可能会面临的访问压力,所以必须要考察系统在高并发访问情况下,超出负载设计能力的情况下可能会出现的性能问题。网站需要长时间持续运行,还必须保证系统在持续运行且访问压力不均匀的情况下保持稳定的性能特性。

可用性

对于大型网站而言,特别是知名网站,网站宕掉、服务不可用是一个重大的事故, 轻则影响网站声誉,重则可能会摊上官司。对于电子商务类网站,网站不可用还意味着 损失金钱和用户。因此几乎所有网站都承诺7x24可用,但事实上任何网站都不可能达到 完全的7x24可用,总会有一些故障时间,扣除这些故障时间,就是网站的总可用时间, 这个时间可以换算成网站的可用性指标,以此衡量网站的可用性,一些知名大型网站可 以做到4个9以上的可用性,尤是可用性超过99.99%。

因为网站使用的服务器硬件通常是普通的商用服务器,这些服务器的设计目标本身并不保证高可用,也就是说,很有可能会出现服务器硬件故障,也就是俗称的服务器宕机。大型网站通常都会有上万台服务器,每天都必定会有一些服务器宕机,因此网站高 可用架构设计的前提是必然会出现服务器宕机,而高可用设计的目标就是当服务器宕机的时候,服务或者应用依然可用。

网站高可用的主要手段是冗余,应用部署在多台服务器上同时提供访问,数据存储 在多台服务器上互相备份,任何一台服务器宕机都不会影响应用的整体可用,也不会导致数据丢失。

对于应用服务器而言,多台应用服务器通过负载均衡设备组成一个集群共同对外提供服务,任何一台服务器宕机,只需把请求切换到其他服务器就可实现应用的高可用, 但是一个前提条件是应用服务器上不能保存请求的会话信息。否则服务器宕机,会话丢失,即使将用户请求转发到其他服务器上也无法完成业务处理。。———— 采用统一的缓存服务器来存储会话信息,也可以解决登陆后,可以在多个网页保存用户登陆态。

对于存储服务器,由于其上存储着数据,需要对数据进行实时备份,当服务器宕机 时需要将数据访问转移到可用的服务器上,并进行数据恢复以保证继续有服务器宕机的时候数据依然可用。

除了运行环境,网站的高可用还需要软件开发过程的质量保证。通过预发布验证、 自动化测试、自动化发布、灰度发布等手段,减少将故障引入线上环境的可能,避免故 障范围扩大。

衡量一个系统架构设计是否满足高可用的目标,就是假设系统中任何一台或者多台 服务器宕机时,以及出现各种不可预期的问题时,系统整体是否依然可用。

伸缩性

大型网站需要面对大量用户的高并发访问和存储海量数据,不可能只用一台服务器 就处理全部用户请求,存储全部数据。网站通过集群的方式将多台服务器组成一个整体 共同提供服务。所谓伸缩性是指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。

衡量架构伸缩性的主要标准就是:

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

对于应用服务器集群:

  • 只要服务器上不保存数据,所有服务器都是对等的,通过使用合适的负载均衡设备就可以向集群中不断加入服务器。

对于缓存服务器集群:

  • 加入新的服务器可能会导致缓存路由失效,进而导致集群中 大部分缓存数据都无法访问。虽然缓存的数据可以通过数据库重新加载,但是如果应用已经严重依赖缓存,可能会导致整个网站崩溃。需要改进缓存路由算法保证缓存数据的可访问性。

关系数据库虽然支持数据复制,主从热备等机制,但是很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩性方案必须在数据库之外实现,通过路由分区等手段 将部署有多个数据库的服务器组成一个集群。

至于大部分NoSQL数据库产品,由于其先天就是为海量数据而生,因此其对伸缩性 的支持通常都非常好,可以做到在较少运维参与的情况下实现集群规模的线性伸缩。

扩展性

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

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

网站可伸缩架构的主要手段是事件驱动架构和分布式服务。

事件驱动架构在网站通常利用消息队列实现,将用户请求和其他业务事件构造成消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理。通过这 种方式将消息产生和消息处理分离开来,可以透明地增加新的消息生产者任务或者新的消息消费者任务。

分布式服务则是将业务和可复用服务分离开来,通过分布式服务框架调用。新增产品可以通过调用可复用的服务实现自身的业务逻辑,而对现有产品没有任何影响。可复用服务升级变更的时候,也可以通过提供多版本服务(istio)对应用实现透明升级,不需要强制应用同步变更。

大型网站为了保持市场地位,还会吸引第三方开发者,调用网站服务,使用网站数据开发周边产品,扩展网站业务。第三方开发者使用网站服务的主要途径是大型网站提供的开放平台接口。

安全性

互联网是开放的,任何人在任何地方都可以访问网站。网站的安全架构就是保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取。

衡量网站安全架构的标准就是针对现存和潜在的各种攻击与窃密手段,是否有可靠的应对策略。

文章来源

  • 作者:李智慧
  • 来源:《大型网站技术架构》
Last Updated:
Contributors: klc407073648
Prev
第2章 - 大型网站架构模式
Next
第4章 - 瞬时响应:网站的高性能架构