书籍介绍:https://book.douban.com/subject/25723064/
大型网站系统特点
高并发、大流量:PV量巨大
高可用:7*24小时不间断服务
海量数据:
- 文件数目分分钟xxTB
用户分布广泛,网络情况复杂:网络运营商
安全环境恶劣:黑客的攻击
需求快速变更,发布频繁:快速适应市场,满足用户需求
渐进式发展:慢慢地运营出大型网站
架构演化
大型网站架构演化过程
初始阶段网站架构:
- 一台Server就刚需—应用程序、数据库、文件等所有资源都集中在一台Server上,典型案例:
- 基于LAMP架构的PHP网站
应用和数据服务分离:
- 三台Server平天下—业务发展,单台不再适应业务的发展
- 将应用和数据分离后成三台Sever(应用服务器、文件服务器与数据库服务器)
分离后三台
Server
对硬件资源的需求各不相同:
- 应用服务器需要更快更强大的CPU,而数据库服务器需要更快的硬盘和更大的内存,文件服务器则需要更大的硬盘
使用缓存改善网站性能:
- 3+X的
Server
模式**—**减少数据库访问压力,提高网站的数据访问速度缓存又可以分为:
本地缓存和远程缓存(可以是分布式的),本地缓存访问速度快,但数据量有限
远程分布式缓存可以集群,因此容量不受限制
使用应用服务器集群改善网站并发处理能力:
- 集群—解决高并发、海量数据问题的常用手段,实现系统的可伸缩性
通过负载均衡调度器,可将用户访问分发到集群中的某台
Server
上,应用服务器的负载压力不再成为整个网站的瓶颈
数据库读写分离:
使用缓存后绝大部分都可以不通过DB就能完成,但仍有一部分(缓存访问不命中、缓存过期)和全部的写操作需要访问DB
- 在网站的用户达到一定规模后,DB因为负载压力过高成为网站的瓶颈
大部分主流DB都提供主从热备功能,利用这一功能就可以配置两台DB主从关系,一台数据更新同步到另一台Server上
网站利用DB的这一功能,实现DB读写分离,从而改善DB负载压力
使用反向代理和CDN加速网站响应:
- CDN和反向代理的基本原理都是缓存,区别在于CDN部署在网络提供商的机房,而反向代理则部署在网站的中心机房
使用CDN和反向代理的目的都是尽早返回数据给用户:
- 一方面加快用户访问速度,另一方面也减轻后端服务器的负载压力
使用分布式文件系统和分布式数据库系统:
- 随着网站业务的发展,两台DB服务器依然不能满足需求,文件系统也一样
使用NoSQL和搜索引擎:
NoSQL和搜索引擎都是源自互联网的技术手段,对可伸缩的分布式特性具有更好的支持
- 应用服务器则通过一个统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦
业务拆分:
通过分而治之的手段将整个网站业务分成不同的产品线
- 如淘宝将首页、商铺、订单、卖家、买家等拆分成不同的产品线,分归不同的业务团队负责
各个应用之间可以通过建立一个超链接建立关系,也可以通过消息队列进行数据分发
分布式服务:
既然每一个应用系统都需要执行许多相通的业务操作
- 比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署
大型网站架构演化价值观
核心价值:随网站所需灵活应对
大型网站不是从无到有一步就搭建好一个大型网站,而是能够伴随小型网站业务的渐进发展,慢慢地演化成一个大型网站
驱动力量:
- 网站的业务发展—业务成就了技术,事业成就了人,而不是相反
大型网站架构设计的误区
一味追随大公司的解决方案
为了技术而技术->常见问题
企图用技术解决所有问题:
- 技术是用来解决业务问题的,而业务的问题,也可以通过业务的手段去解决
架构模式
好的设计绝对不是模仿,不是生搬硬套某个模式,而是对问题深刻理解之上的创造与创新
即使是微创新,也是让人耳目一新的似曾相识
山寨与创新的最大区别不在于是否抄袭,是否模仿,而在于对问题和需求是否真正理解与把握
分层
最常见的架构模式,将系统在横向维度上切分成几个部分,每个部分单一职责
网站一般分为三个层次:应用层、服务层和数据层
- 通过分层,一个庞大系统切分成不同部分,便于分工合作和维护
但是,分层架构也有一些挑战:
- 必须合理规划层次边界和接口
- 禁止跨层次的调用及逆向调用
分割
分割是在纵向方面对软件进行切分->将不同的功能和服务分割开来,包装成高内聚低耦合的模块单元
- 有助于软件开发和维护,还便于不同模块的分布式部署,提高网站的并发处理能力和功能扩展能力
分布式
分布式应用和服务:
- 应用和服务模块分布式部署,便于业务功能扩展
分布式静态资源:
- JS、CSS、LOGO图片等资源独立部署,采用独立域名->动静分离
分布式数据和存储:
- 传统
RDBMS
分布式部署和NoSQL
产品分布式计算:
- Hadoop及其
MapReduce
分布式计算框架,其特点是移动计算而不是移动数据
集群
多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务
当某台服务器发生故障,负载均衡设备或者系统的失效转移机制将请求转发到集群中的其他服务器上
- 提高系统的可用性,即所谓的HA(高可用性)
所以,在网站应用中,即使是访问量很小的分布式应用和服务,也至少要部署两台服务器构成一个小集群
缓存
缓存是改善软件性能的第一手段。在复杂的软件设计中,缓存几乎无处不在
CDN:
- 内容分发网络,缓存网站的一些静态资源
反向代理:
- 部署在网站的前端,最先访问到的就是反向代理服务器
本地缓存:
- 在应用服务器本地缓存热点数据,无需访问数据库
分布式缓存:
- 应用程序通过网络通信访问缓存数据
网站应用中,缓存除了可以加快数据访问速度,还可以减轻后端应用和数据存储的负载压力
异步
业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段
- 每个阶段之间通过共享数据的方式异步执行进行协作
异步架构是典型的生产者消费者模式,两者不存在直接调用,只要保持数据结构不变
- 彼此功能实现可以随意变化而不互相影响,这对网站扩展新功能非常便利
异步消息队列可以提高系统可用性、加快网站响应速度,消除并发访问高峰
冗余
要想保证在服务器宕机的情况下网站依然可以继续服务,不丢失数据,就需要一定程度的服务器冗余运行,数据冗余备份
- 这样当某台服务器宕机时,可以将其上的服务和数据访问转移到其他机器上
数据库除了定期备份存档保存实现冷备份之外,为了保证在线业务高可用
- 还需要对数据库进行主从分离,实时同步实现热备份
自动化
在无人值守的情况下,网站可以正常运行,一切都可以自动化是网站的理想状态
目前大型网站的自动化架构设计主要集中在发布运维方面
发布部署过程自动化
自动化代码管理
自动化测试
自动化安全监测
安全
通过密码和手机校验码进行身份验证
对登录、交易等操作进行加密
使用验证码进行识别
对于常见的XSS攻击、SQL注入、编码转换等进行防范
对垃圾或敏感信息进行过滤
对交易转账等操作进行风险控制
架构要素
性能—响应时间决定用户
浏览器端:
浏览器缓存
使用页面压缩
合理布局页面
减少
Cookie
传输CDN:
- 内容分发网络(Content Delivery Network,简称CDN)将加速内容分发至离用户最近的节点
- 缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性
- 解决网络带宽小、用户访问量大、网点分布不均等问题
应用服务器端:
- 服务器本地缓存和分布式缓存
服务器集群技术:
- Web服务器集群、数据库服务器集群、分布式缓存服务器集群等等
- 通过部署多台服务器共同对外提供同类服务,提高整体处理能力
数据库服务器端:
- 索引:索引(index)是对数据库表中一个或多个列
- 例如,employee 表的姓氏 (name) 列)的值进行排序的结构
如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息
要注意的是:
- 建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件
缓存:
- 数据库缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对数据库的物理数据源访问的频次,从而提高了应用的运行性能
SQL优化:
- 当一个基于数据库的应用程序运行起来很慢时,90%的可能都是由于数据访问程序的问题,要么是没有优化,要么是没有按最佳方法编写代码
- 因此你需要审查和优化你的数据访问/处理程序
NoSQL:
- 方兴未艾的
NoSQL
数据库通过优化数据模型、存储结构、伸缩性等手段在性能方面的优势日趋明显
可用性—你能保证几个9
如何衡量可用性?
- 全靠9来撑腰:几乎所有网站都承诺7*24小时可用,但事实上都不可能完全实现,总会有一些故障时间
去除这些故障时间就是网站的总可用时间
换算成网站的可用性指标,以此衡量网站的可用性,例如某些知名网站可用性达到99.99%
哪些手段提高可用性?
- 核心:
- 冗余-各服务器互相备份保证整体可用
- 应用服务器端:
- 通过负载均衡设备建立集群,其中一台宕机立即切换到其他服务器继续提供服务,这就保证了高可用性
- 存储服务器端:
- 需要对数据进行实时备份,当某台宕机立即将数据访问请求转换到其他服务器上,并进行数据恢复以保证数据高可用
伸缩性
衡量标准:
是否可以多态服务器构建集群?
是否容易向集群中添加新服务器?
加入服务器后是否能提供无差别服务?
主要手段:
应用服务器:使用合适的负载均衡设备(硬件还是软件?F5还是
LVS+KeepAlived
)缓存服务器:改进缓存路由算法保证缓存数据的可访问性
数据库服务器:通过路由区分等手段将多服务器组成一个集群
扩展性
衡量标准:增加新业务时是否可以实现对现有产品透明无影响(是否需要对现有业务进行修改匹配?)
主要手段:
- 事件驱动架构:利用消息队列实现
- 分布式服务:将业务和可复用服务分离
安全性
何为安全性?
- 保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取
衡量标准:
- 针对现存和潜在的攻击窃密手段,是否有可靠的应对策略
高性能架构
网站性能测试
性能测试指标:
- 响应时间,并发数,吞吐量,性能计数器
性能测试方法:
- 性能测试,负载测试,压力测试,稳定性测试
性能优化策略:
性能分析:
- 检查请求处理各个环节的日志,分析哪个环节响应时间不合理,检查监控数据分析影响性能的因素
性能优化:
- Web前端优化,应用服务器优化,存储服务器优化
Web前端性能优化
浏览器访问优化
CDN
加速:
- CDN(内容分发网络)仍然是一个缓存,它将数据缓存在离用户最近的地方,便于用户以最快速度获取数据
反向代理:
- 反向代理服务器位于网站机房,代理网站Web服务器接收Http请求,对请求进行转发
反向代理服务器具有以下功能:
- 保护网站安全:
- 任何来自Internet的请求都必须先经过代理服务器
- 通过配置缓存功能加速Web请求:
- 减轻真实Web服务器的负载压力
- 实现负载均衡:
- 均衡地分发请求,平衡集群中各个服务器的负载压力
应用服务器性能优化
分布式缓存:
缓存本质是一个内存Hash表,数据以(Key,Value)形式存储在内存中
缓存主要用来存放那些读写比很高、很少变化的数据,如商品的类目信息、热门商品信息等
这样,应用程序读取数据时,先到缓存中取,如缓存中没有或失效,再到数据库中取出,重新写入缓存以供下一次访问
因此,可以很好地改善系统性能,提高数据读取速度,降低存储访问压力
分布式缓存架构:
一方面是以以JBoss Cache为代表的互相通信派
另一方面是以Memcached为代表的互不通信派
JBoss Cache
需要将缓存信息同步到集群中的所有机器,代价比较大而Memcached采用一种集中式的缓存集群管理,缓存与应用分离部署
应用程序通过一致性Hash算法选择缓存服务器远程访问缓存数据,缓存服务器之间互不通信
因而集群规模可以轻易地扩容,具有良好的伸缩性
异步操作:
使用消息队列将调用异步化,可改善网站的扩展性,还可改善网站性能
消息队列具有削峰的作用->将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务
使用集群:
- 在高并发场景下,使用负载均衡技术为一个应用构建多台服务器组成的服务器集群
- 可以避免单一服务器因负载压力过大而响应缓慢,使用户请求具有更好的响应延迟特性
代码优化:
多线程:
- 使用多线程的原因:一是IO阻塞,二是多CPU,都是为了最大限度地利用CPU资源,提高系统吞吐能力,改善系统性能
资源复用:
- 目的是减少开销很大的系统资源的创建和销毁
数据结构:
- 在不同场合合理使用恰当的数据结构,可以极大优化程序的性能
垃圾回收:
- 理解垃圾回收机制有助于程序优化和参数调优,以及编写内存安安全的代码
存储性能优化
机械硬盘 还是 固态硬盘?
机械硬盘:通过马达驱动磁头臂,带动磁头到指定的磁盘位置访问数据
- 它能够实现快速顺序读写,慢速随机读写
固态硬盘(又称SSD):
- 无机械装置,数据存储在可持久记忆的硅晶体上,因此可以像内存一样快速随机访问
在目前的网站应用中,大部分应用访问数据都是随机的,这种情况下SSD具有更好的性能表现,但是性价比有待提升
NoSQL(例如:HBase)产品广泛采用
LSM
树
高可用架构
可用性度量与考核
如何度量网站可用性?
- 一个神奇的数字—9!你有几个9,就代表了你的可用性
- 例如QQ可用性达到了4个9:99.99%
如何考核网站可用性?
- 广泛采用故障分的,它是对网站故障进行分类加权计算故障责任的方法
高可用的架构
设计的目的?
- 保证服务器硬件故障服务依然可用,数据依然保存并能够被访问
主要的手段?
数据和服务的冗余备份以及失效转移:
对于服务而言,一旦某个服务器宕机,就将服务切换到其他可用的服务器上
对于数据而言,如果某个磁盘损坏,就从备份的磁盘(事先就做好了数据的同步复制)读取数据
高可用的应用
应用层处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性
通过负载均衡进行无状态服务的失效转移
应用服务器集群的
Session
管理
高可用的服务
高可用的服务模块为业务产品提供基础公共服务,在大型站点中这些服务通常都独立分布式部署,被具体应用远程调用
在具体实践中,有以下几点高可用的服务策略可以参考:
分级管理:
- 核心应用和服务具有更高的优先级,比如用户及时付款比能否评价商品更重要
超时设置:
- 设置服务调用的超时时间,一旦超时后,通信框架抛出异常
- 应用程序则根据服务调度策略选择重试or请求转移到其他服务器上
异步调用:
- 通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况
服务降级:
- 网站访问高峰期间,为了保证核心应用的正常运行,需要对服务降级
降级有两种手段:
一是拒绝服务,拒绝较低优先级的应用的调用,减少服务调用并发数,确保核心应用的正常运行
二是关闭功能:
- 关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节约系统开销,为核心应用服务让出资源
幂等性设计:
- 保证服务重复调用和调用一次产生的结果相同
高可用的数据
对于大多数网站而言,数据是其最宝贵的物质资产
保证数据高可用的主要手段有两种:一是数据备份,二是失效转移机制
数据备份:
- 又分为冷备份和热备份,冷备份是定期复制,不能保证数据可用性
失效转移:
- 若数据服务器集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都要重新路由到其他服务器
- 保证数据访问不会失败
高可用的QA
网站发布:
- 在柔性的发布过程中,每次关闭的服务都是集群中的一小部分,并在发布完成后立即可以访问
自动化测试:
- 使用自动测试工具或脚本完成测试
预发布验证:
- 引入预发布服务器,与正式服务器几乎一致,只是没有配置在负载均衡服务器上,外部用户无法访问
代码控制:
- 目前大多数网站采用SVN,分支开发,主干发布模式
另外,目前开源社区广泛采用
Git
作为版本控制工具,正逐步取代SVN的地位
网站运行监控
不允许没有监控的系统上线
监控数据采集
监控管理:
系统报警:
- 配置报警阀值和值守人员联系方式,系统发生报警时,即使工程师在千里之外,也可以被及时通知
失效转移:
- 监控系统在发现故障时,主动通知应用进行失效转移
自动优雅降级:
- 为了应付网站访问高峰,主动关闭部分功能,释放部分系统资源,保证核心应用服务的正常运行
网站柔性架构的理想状态
伸缩性架构
网站架构的伸缩性设计
不同功能进行物理分离实现伸缩
纵向分离:
- 将业务处理流程上得不同部分分离部署,实现系统的伸缩性
横向分离:
- 将不同的业务模块分离部署,实现系统的伸缩性
单一功通过集群规模实现伸缩
使用服务器集群,即将相同服务部署在多台服务器上构成一个集群整体对外提供服务
- 具体来说,集群伸缩性又分为应用服务器集群伸缩性和数据服务器集群伸缩性
这两种集群对于数据状态管理的不同,技术实现也有很大的区别
应用服务器集群的伸缩性设计
应用服务器那点必须知道的事儿
应用服务器应该被设计成无状态的,即应用服务器不存储请求上下文信息
构建集群后,每次用户的请求都可以发到集群中任意一台服务器上处理,任何一台服务器的处理结果都是相同的
HTTP本身是一个无状态的连接协议,为了支持客户端与服务器之间的交互
- 我们就需要通过不同的技术为交互存储状态,而这些不同的技术就是Cookie和Session了
HTTP请求的分发是应用服务器集群实现伸缩性的核心问题,而负载均衡服务器就是HTTP请求的分发装置
- 它是网站必不可少的基础手段,也被称为网站的杀手锏之一
负载均衡技术—网站必不可少的基础技术手段
负载均衡的实现方式多种多样,从硬件到软件,从商业产品到开源产品,应有尽有
但是,实现负载均衡的基础技术不外乎以下几种:
HTTP
重定向负载均衡
DNS
域名解析负载均衡反向代理负载均衡
IP
负载均衡数据链路层负载均衡
可扩展架构
可伸缩与可扩展
扩展性(Extensibiltiy)
- 指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力
指系统能够通过增加(或减少)自身资源规模的方式增强(或减少)自己计算事务的能力
- 在网站架构中,通常是指利用集群的方式增加服务器数量,从而提高系统的整体事务吞吐能力
设计网站可扩展架构的核心思想是:模块化,并在此基础之上降低模块间的耦合,提高模块的复用性
在大型网站中,这些模块通过分布式部署的方式,独立的模块部署在独立的服务器(集群)上
- 从物理上分离模块之间的耦合关系,进一步降低耦合性从而提高复用性
安全性架构
网站应用攻击与防御
信息加密技术与密钥安全
电子商务风险控制