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

  • 初始阶段的网站架构:应用程序、数据库、文件等所有的资源都在一台服务器上
  • 应用服务和数据服务分离:应用服务器、文件服务器和数据库服务器
  • 使用缓存改善网站性能:本地缓存、远程分布式缓存
  • 使用应用服务器集群改善网站的并发处理能力:通过负载均衡调度服务器,可将来自用户浏览器的访问请求分发到应用服务器集群中的任何一台服务器上
  • 数据库读写分离:应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库
  • 使用反向代理和 CDN 加速网站响应
  • 使用分布式文件系统和分布式数据库系统:将不同业务的数据库部署在不同的物理服务器上
  • 使用 NoSQL 和搜索引擎
  • 业务拆分:将整个网站业务分成不同的产品线
  • 分布式服务(微服务)

    布式服
    图 1 布式服

网站架构模式

  • 分层:应用层、服务层、数据层
  • 分割
  • 分布式:将不同模块部署在不同的服务器上,通过远程调用协同工作,常用方案:分布式应用和服务、分布式静态资源(动静分离)、分布式数据和存储、分布式计算
  • 集群
  • 缓存:CDN、反向代理、本地缓存、分布式缓存
  • 异步
  • 冗余:服务器冗余运行,数据冗余备份
  • 自动化
  • 安全

系统吞吐量

  • QPS(Queries Per Second,每秒查询率),是指一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
  • TPS(Transactions Per Second,每秒事务数),软件测试结果的测量单位,一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程,客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数
  • RT(响应时间)
  • 系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间
    • QPS(TPS):每秒钟 request/事务数
    • 响应时间:一般取平均响应时间
    • 并发数:系统同时处理的 request/事务数
  • 计算公式
    • QPS(TPS)= 并发数/平均响应时间
    • 并发数 = QPS(TPS)* 平均响应时间

网站的高性能架构

Web 前端性能优化

浏览器访问优化

  • 减少 http 请求:合并 CSS、合并 JavaScript、合并图片
  • 使用浏览器缓存静态资源文件:更新静态资源文件时修改文件名
  • 启用压缩:GZip 压缩
  • CSS 放在页面最上面、JavaScript 放在页面最下面
  • 减少 Cookie 传输:减少 Cookie 中传输的数据量;静态资源使用独立域名访问,减少 Cookie 传输的次数,突破浏览器连接限制

CDN 加速

  • CDN(Content Distribute Network,内容分发网络),部署在网络运营商机房,通过将静态页面内容分发到离用户最近的 CDN 服务器,使用户可以通过最短路径获取内容

反向代理

  • 动静分离、负载均衡

应用服务器性能优化

分布式缓存

  • 网站访问数据的特点大多数呈现在"二八定律"(80% 的业务访问集中在 20% 的数据上),这时为了减轻数据的压力和提高网站的数据访问速度,则可以使用缓存机制来优化网站
  • 缓存的基本原理:数据缓存以一对 Key、Value 的形式存储在内存 Hash 表中,KV 对中 Key 的 HashCode 对应的 Hash 表索引
  • 分布式缓存架构:Memcached

异步操作

  • 将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作
  • 在单一服务器内部可通过多线程共享内存队列的方式实现异步,多个服务器集群通过分布式消息队列实现异步

使用集群

  • 多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务

代码优化

  • 多线程解决线程安全:将对象设计为无状态对象、使用局部对象、并发访问资源时使用锁
  • 资源复用:单例(Service、Dao)、对象池(数据库连接池、Web 应用服务器线程池)
  • 数据结构
  • 垃圾回收

存储性能优化

  • 机械硬盘 vs 固态硬盘、B+ 树 vs LSM 树、RAID vs HDFS

网站的高可用架构

  • 数据和服务的冗余备份及失效转移

高可用的应用

  • 位于应用层的服务器通过负载均衡设备将一组服务器组成一个集群共同对外提供服务
  • 当负载均衡设备通过心跳检测等手段监控到某台应用服务器不可用时,就将其从集群列表中剔除,并将请求分发到集群中其他可用的服务器上,使整个集群保持可用,从而实现应用高可用

  • 通过负载均衡进行无状态服务的失效转移

  • 应用服务器集群的 Session 管理

    • 在集群中的服务器之间同步 Session 对象(Session 复制)
    • 利用负载均衡的 ip_hash 算法实现 Session 绑定
    • 利用 Cookie 记录 Session
    • 利用独立部署的 Session 服务器(集群)统一管理 Session:利用分布式缓存、数据库等;利用 Session 服务集成单点登录(SSO)、用户服务等

高可用的服务

  • 位于服务层的服务器也是通过集群方式实现高可用
  • 这些服务器被应用层通过分布式服务调用框架访问,分布式服务调用框架会在应用层客户端程序中实现软件负载均衡,并通过服务注册中心对提供服务的服务器进行心跳检测,发现有服务不可用,立即通知客户端程序修改服务访问列表,剔除不可用的服务器

  • 高可用的服务策略

    • 分级管理
    • 超时设置
    • 异步调用:对服务的调用通过消息队列等异步方式完成
    • 服务降级:拒绝低优先级应用的调用、关闭不重要的服务
    • 幂等性设计:保证服务重复调用和调用一次产生的结果相同

高可用的数据

  • 数据备份:位于数据层的服务器需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份
  • 失效转移:当数据服务器宕机时,应用程序将访问切换到有备份数据的服务器上

网站的伸缩性架构

  • 伸缩性:系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力

网站架构的伸缩性设计

  • 根据不同功能进行物理分离实现伸缩:不同的服务器部署不同的服务,提供不同的功能(分层后分离、业务分割后分离)
  • 单一功能通过集群实现伸缩:集群内的多台服务器部署相同的服务,提供相同的功能

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

  • 利用 HTTP 重定向协议实现负载均衡
  • 利用 DNS 处理域名解析请求的同时进行负载均衡处理
  • 利用反向代理服务器进行负载均衡
  • 在网络层通过修改请求目标地址进行负载均衡
  • 在数据链路层修改 mac 地址进行负载均衡
  • 负载均衡算法:轮询(Round Robin,RR)、加权轮询(Weighted Round Robin, WRR)、随机(Random)、最少连接(Least Connections)、源地址散列(Source Hashing)

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

  • Memcached、Redis
  • 一致性 Hash 算法

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

  • 关系数据库集群的伸缩性设计:数据库主从读写分离、数据分库、数据分片
  • NoSQL 数据库的伸缩性设计:HBase

网站的可扩展架构

  • 扩展性:对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力
  • 模块化设计,并在此基础之上,降低模块间的耦合性,提高模块的复用性

利用分布式消息队列降低系统耦合性

  • 通过消息对象分解系统耦合性,不同子系统处理同一个消息
  • 事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作
  • 将用户请求和其他业务事件构造成消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理
  • ActiveMQ、Kafka

利用分布式服务打造可复用的业务平台

  • 通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用

  • 纵向拆分:将一个大应用拆分为多个小应用

  • 横向拆分:将复用的业务拆分出来,独立部署为分布式服务

  • 常见分布式服务框架:Dubbo、Thrift、gRPC、Finagle

可扩展的数据结构

网站的安全架构

网站应用攻击与防范

XSS 攻击

  • Cross Site Script,跨站点脚本攻击
  • 攻击者在网页中嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作
  • 防范:对用户输入的数据中的“尖括号”、“单引号”、“引号”之类的特殊字符进行 HTML 转义处理

CRSF 攻击

  • Cross Site Request Forgery,跨站点请求伪造
  • 攻击者利用了浏览器 cookie 或服务器 session 策略,盗取用户身份,然后通过跨站请求(存在 CSRF 漏洞的应用/网站),在用户不知情的情况下,以用户的身份伪造请求进行非法操作
  • 防范:在 cookie 中设置 "HttpOnly" 属性;增加 token 校验;通过 HTTP 头中的 Referer 识别该 HTTP 请求的来源地址

SQL 注入攻击

  • 通过把 SQL 命令伪装成正常的 HTTP 请求参数,传递到服务端,欺骗服务器最终执行恶意的 SQL 命令,达到入侵目的
  • 防范:使用预编译语句;处理好相应的异常

文件上传漏洞

  • 攻击者利用一些站点没有对文件的类型做很好的校验,上传了可执行的文件或者脚本,并且通过脚本获得服务器上相应的权利,或者是通过诱导外部用户访问、下载上传的病毒或木马文件,达到攻击的目的
  • 防范:通过魔数来判断文件类型;对于图片类型的文件,在上传后对图片进行相应的缩放,破坏恶意用户上传的二进制可执行文件的结构,来避免恶意代码执行(ImageMagick)

DDoS 攻击

  • Distributed Denial of Service,分布式拒绝服务攻击
  • 攻击者借助公共网络,将数量庞大的计算机设备联合起来作为攻击平台,对一个或多个目标发动攻击,从而达到瘫痪目标主机的目的

其它常见攻击手段

  • DNS 域名劫持、CDN 回源攻击、服务器权限提升、缓冲区溢出

Web 应用防火墙

  • ModeSecurity

信息加密技术及密钥安全管理

信息加密技术

  • 单向散列加密:通过对不同输入长度的信息进行散列计算,得到固定长度的输出(数字摘要),常用算法:MD5、SHA
  • 对称加密:加密和解密使用的密钥是同一个密钥(可以互相推算),常用算法:DES(Data Encrytion Standard)、RC5、AES(Advanced Encryption Standard)
  • 非对称加密:用公钥加密的信息必须用私钥才能解开,反之,用私钥加密的信息只有用公钥才能解开,常用算法:RSA

    信息加密技术
    图 2 信息加密技术

数字签名

  • 通信正文经过相应的摘要算法生成摘要后,使用消息发送者的私钥进行加密,生成数字签名,然后将消息正文与数字签名一起传输给信息的接收者
  • 接收者接收到消息的正文和对应的数字签名后,使用与发送端相同的摘要算法,生成通信正文的摘要,并且使用发送者的公钥对数字签名进行解密,得到发送端生成的摘要,进行比较后即可验证发送者的身份是否合法,正文的内容是否被篡改

数字证书

证书签名的生成
图 3 证书签名的生成

证书校验的过程
图 4 证书校验的过程

密钥安全管理

  • 把密钥和算法放在一个独立的服务器,对外提供加密和解密服务,应用系统通过调用这个服务,实现数据的加解密
  • 将加解密算法放在应用系统中,密钥则放在独立服务器中

信息过滤与反垃圾

布式计
图 5 布式计