大型网站架构演化
大型网站的关注指标
- 高可用
- 高性能
- 易扩展
- 可伸缩
- 安全
大型网站的特点
- 高并发,大流量
- 高可用
- 海量数据
- 用户分布广泛,网络情况复杂
- 安全环境恶劣
- 需求快速变更,发布频繁
- 渐进式发展
大型网站架构演化发展过程
- 初始阶段,一般使用LAMP来搭建,所有资源存放在一台服务器上
- 应用服务和数据服务分离,有独立的数据库服务器
- 使用缓存改善网站性能,依据是二八定律:80%的业务访问集中在20%的数据上
- 这里需要考虑哪些数据适合缓存
- 缓存可以是本地缓存,也可以是远程分布式缓存
- 使用应用服务器集群改善网站的并发处理能力
- 如果能通过增加一台服务器的方式来改善负载压力,就可以以同样的方式持续增加服务器来不断改善系统性能,从而实现系统的可伸缩性
- 这里需要考虑使用哪些负载均衡的策略
*数据库读写分离 - 缓存中的数据,如果更新过快,那么会持续刷新缓存,从而降低性能
- 可以利用主流数据库提供的主从热备功能,通过配置两台数据库的朱从关系,将一台数据库服务器上的数据同步到另外一台上面
- 使用反向代理和CDM加速网络响应
- CDN和反向代理的基本原理都是缓存
- CDN部署在网络提供商的机房,用户在请求网络服务时,可以从距离自己最近的网络提供商机房获取数据
- 反向代理部署在网站的中心机房,当用户的请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,那么就将其直接返回给用户
- 使用分布式文件系统和分布式数据库系统
- 网站常用的数据库拆分手段是业务分库,即将不同业务的数据库部署到不同的物理服务器上
- 使用NoSQL和搜索引擎
- 业务拆分,使用分而治之的手段将整个网站业务分成不同的产品线
- 分布式服务
大型网站架构演化的价值观
网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的。因此对于小型网站来说,最需要做的是位用户提供好的服务来创造价值,得到用户的认可,从而活下去,野蛮生长。
- 大型网站架构技术的核心价值是随网站所需灵活应对, 它是一个演化的过程
- 驱动大型网站技术发展的主要力量是网站的业务发展,是业务成就了技术,而不是相反。因此要摒弃为了技术而技术的套路
大型网站架构模式
- 分层,这是在横向方向对系统进行切分
- 分层的挑战在于必须合理规划层次边界和接口
- 分层包括物理分层和逻辑分层两种
- 分割,这是在纵向方向对系统进行切分
- 将不同的功能和服务分割开来,包装秤高内聚低耦合的模块单元
- 分布式
- 分层和分割的目的在于小模块便于分布式部署
- 带来的问题:1) 分布式意味着服务调用必须通过网络,需要考虑带宽的影响;2) 服务器越多,宕机的概率越大
- 常用的分布式方案:1) 分布式应用和服务; 2) 分布式静态资源; 3) 分布式数据和存储; 4) 分布式计算;5) 分布式配置、分布式锁、分布式文件系统。。。
- 集群,即多台服务器部署相同的应用,从而构成一个集群,通过负载均衡设备共同对外提供服务
- 即使访问量很小的分布式应用和服务,也至少要部署到两台服务器来构成一个小集群,这样可以提高系统的可用性
- 缓存,即将数据放在距离计算最近的位置以加快处理速度
- CDN
- 反向代理
- 本地缓存
- 分布式缓存
- 异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方法异步进行协作
- 通常需要使用消息队列
- 带来的好处:1) 提高系统可用性; 2) 加快网站响应速度; 3) 消除并发访问高峰
- 冗余
- 集群带来的必然结果
- 安全需求的必然结果
- 自动化,DevOps思维,尽量减少人工干预
- 自动化发布
- 自动化代码管理
- 自动化测试
- 自动化安全监测
- 自动化部署
- 自动化监控
- 自动化报警
- 自动化失效转移、恢复
- 自动化分配资源
- ......
- 安全
大型网站核心架构要素
- 性能
- 一个性能问题可能会导致网站用户严重流失
- 衡量性能的指标:响应时间、TPS、系统性能计数器等
- 可用性
- 没有网站可以完美的7*24运行
- 网站高可用结构的前提是必然会出现服务器宕机,儿高可用设计的目标是当服务器宕机时,服务或者应用依然可用
- 必要的手段是集群,即冗余
- 伸缩性,即通过不断向集群中加入服务器的手段来环节不断上升的用户并发访问压力和不断增长的数据存储需求
- 衡量标准:是否可以构建集群;是否可以方便的向集群中添加新的服务器
- 扩展性,直接关注网站的功能,保证可以快速响应需求变更
- 衡量标准: 网站增加新的业务产品时,是否对现有业务透明无影响
- 安全性
- 衡量标准: 针对现存和潜在的各种攻击和窃密手段,是否可以有效的应对
瞬时响应 - 高性能架构
不同视角下的网站性能
- 用户视角
- 主要是端到端的感觉
- 主要通过前段优化的手段来提升用户体验
- 开发人员视角
- 主要关注应用程序本身以及相关子系统的性能,包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等
- 主要优化手段: 使用缓存加速数据读取、使用集群提高吞吐能力、使用异步消息加快请求响应、使用代码优化提升程序性能
- 运维人员视角
- 主要关注基础设施性能和资源利用率
- 主要优化手段: 建设优化骨干网、使用高性价比定制服务器、利用虚拟化技术优化资源利用率
性能测试指标
- 响应时间,即应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间
- 并发数,即系统能够同时处理的请求的数目,也反映了系统的负载特性
- 吞吐量,即单位时间内系统处理的请求数量,体现系统的整理处理能力
- 性能计数器, 描述服务器或者操作系统性能的一些数据指标
性能测试方法
- 性能测试,以系统设计初期规划的性能指标为预期目标,对系统不断增压,验证系统在资源可接受范围内,是否能达到性能预期
- 负载测试,对系统不断的增加并发请求,知道系统的某项或者多项性能指标达到安全临界值
- 压力测试,超过安全负载的情况下,继续对系统增压,直到系统崩溃或者不能再处理任何请求
- 稳定性测试,在特定硬件、软件、网络情况下,给系统加载一定压力,是系统运行较长一段时间,来观察系统是否稳定
Web前段优化
- 浏览器访问优化
- 减少http请求
- 使用浏览器缓存
- 启用压缩
- CSS放在页面最上面,JavaScript放在页面最下面
- 减少Cookie传输
- CDN加速
- 反向代理
应用服务器性能优化
- 分布式缓存
- 缓存从本质上来说,就是一个内存hash表
- 缓存需要缓存那些读写比很高、很少变化的数据,一般来说读写比在2:1以上时,缓存才有意义
- 应用程序读取数据时,首先到缓存中读取,如果缓存不存在或者已失效,再访问数据库,同时将新的数据放入缓存
- 缓存也需要注意缓存热点数据
- 缓存预热,在新启动的缓存系统中,在启动时就加载热点数据,这样启动后就可以直接使用
- 缓存穿透, 应用持续大量访问不存在的数据,因为这类数据不存在于缓存中,因此会大量访问数据库,从而降低性能
- 对于分布式缓存来说,目前有两类:1) 不同的缓存服务器之间进行通信,例如JBoss Cache;2)不同缓存服务器之间不进行通信,例如Memcached
- 异步操作
- 一般会使用消息队列,带来的额外好处是会削平峰值
- 使用集群
代码优化
- 多线程
- 需要注意线程安全问题,方法:1) 将对象设计成无状态对象;2) 使用局部对象;3) 并发访问资源时使用锁
- 资源复用
- 主要是单例和资源池(对象池)
- 数据结构,选择合适的算法
- 垃圾回收
- 合理设置垃圾回收策略
存储性能优化
- 机械硬盘 vs 固态硬盘
- B+树 vs LSM树
- RAID vs HDFS
万无一失 - 高可用架构
网站的可用性描述网站可以有效访问的特性,它不同于易用性
网站可用性度量
- 网站不可用时间 = 故障修复时间点 - 故障发现时间点
- 网站年度可用性指标 = (1 - 网站不可用时间/年度总时间)* 100%
- 一般以几个9来表示,2个9是基本可用,网站年度不可用时间小于88小时;3个9是较高可用,网站年度不可用时间小于9小时;4个9是具有自动恢复能力的高可用,网站年度不可用时间小于53分钟;5个9是极高可用性,网站年度不可用时间小于5分钟
网站高可用架构的设计目标是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问
网站高可用架构的主要手段:数据和服务的冗余备份以及失效转移,一旦服务器宕机,就将服务切换至其他可用的服务器上。
高可用的应用
无状态应用: 应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例之间完全对等,请求提交到任何一个服务器上,处理的结构都是相同的
- 通过负载均衡进行无状态服务的失效转移
- 负载均衡: 主要使用在业务量和数据量较高的情况下,当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上, 以提升整体的负载处理能力
- 应用服务器集群的Session管理
- Session复制
- Session绑定
- 利用Cookie记录Session
- Session服务器
高可用的服务
- 分级管理
- 超时设置
- 异步调用
- 服务降级
- 幂等性设计
高可用的数据
- 主要手段:数据备份和失效转移
- CAP原理: 一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Parition Tolerance)这三个条件
- 数据一致性分类: 1) 数据强一致; 2) 数据用户一致; 3) 数据最终一致
- 数据备份
- 冷备的优点是简单和链家,成本和技术难度较低,缺点是不能保证数据最终一致
- 热备分为两种:1) 异步热备; 2) 同步热备
- 失效转移
- 失效确认:1) 心跳检测;2) 应用程序访问失败报告
- 访问转移
- 数据恢复
高可用网站的软件质量保证
- 网站发布,它的过程和服务器宕机效果箱单,其对系统可用性的影响也 类似
- 一般采取批量更新的方式进行,不会一次关掉集群中的全部服务器
- 自动化测试
- 一般使用Selenium来进行测试
- 预发布验证
- 预发布服务器是一种特殊用途的服务器,它和线上的正式服务器唯一的区别是没有配置在负载均衡服务器上,外部用户无法访问
- 代码控制
- 主干开发,分支发布
- 分支开发,主干发布,这是目前使用的主流方式
- 自动化发布
- 火车模型:将每个应用的发布过程看做一次火车旅程,火车定点运行,期间有若干站点,每一站都进行例行检查,不通过的项目下车,通过的项目继续坐着火车旅行,直到火车到达终点。
- 实际中,可能所有项目在途中都下车了,这样火车不得不回到原点,等待问题解决后再来一次
- 一种可能是火车上的重点项目如果失败,那么整趟火车需要返回
- 人的干预越少,自动化程度越高,引入故障的可能性就越小
- 灰度发布
- 大型网站都会使用灰度发布模式,将集群服务器分成若干部分,每天只发布一部分服务器,观察运行稳定没有故障,第二天继续发布一部分服务器,持续几天你才把整个集群全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可
网站运行监控
- 监控数据采集
- 用户行为日志收集
- 服务器性能监控
- 运行数据报告
- 监控管理
- 系统报警
- 失效转移
- 自动优雅降级
永无止境 - 可伸缩性架构
网站伸缩性: 在不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力
网站架构的伸缩性设计
- 不同功能进行物理分离实现伸缩
- 单一功能通过集群规模实现伸缩
应用服务器集群的伸缩性设计
- HTTP重定向负载均衡
- DNS域名解析负载均衡
- 反向代理负载均衡
- IP负载均衡
- 数据链路层负载均衡
- 负载均衡算法
- 轮询
- 加权轮询
- 随机
- 最小链接
- 原地址散列
分布式缓存集群的伸缩性设计
- Memcached分布式缓存集群的访问模型
- 用用程序通过Memcached客户端访问Memcached服务器集群,Memcached客户端主要由一组API、Memcached服务器集群路由算法、Memcached服务器集群列表以及通信模块构成
- 路由算法负责根据应用程序输入的缓存数据KEY计算得到应该将数据写入到Memcached的哪台服务器(写缓存)或者应该从哪台服务器读数据(读缓存)
- Memcached分布式缓存集群的伸缩性挑战
- 挑战主要针对路由算法,当集群扩容时,如何保证路由算法可以得到新加入的服务器?
- 解决方法: 在网站访问量最少的时候扩容,然后通过模拟请求的方法逐渐预热缓存,使得缓存服务器中的数据重新分布
- 分布式缓存的一致性Hash算法
数据存储服务器集群的伸缩性设计
- 数据存储服务器必须保证数据的可靠存储,任何情况下都必须保证数据的可用性和正确性
- 关系数据库集群的伸缩性设计
- 利用主从结构实现读写分离
- 根据不同业务的数据,放到不同的数据库集群中,即数据库分库
- 对于特别大的表,进行分片处理
- NoSQL数据库的伸缩性设计
- HBase
随需应变 - 可扩展架构
可扩展性:在对现有系统影响最小的情况下,系统功能可持续扩展或者提升的能力
实现可扩展的手段:低耦合,高内聚
利用分布式消息队列降低系统耦合性
事件驱动架构(Event Driven Architecture)
- 定义:通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作。典型的场景是生产着消费者模型
分布式消息队列
利用分布式服务打造可服用的业务平台
- 需要将超大型的、复杂系统查分成可独立部署的模块,从而降低耦合性
- Web Service与企业分布式服务
- Web Service比较臃肿,可以考虑使用REST
- 或者使用开源的解决方案,例如Dubbo
可扩展的数据结构
固若金汤 - 安全架构
典型攻击方式
- XSS攻击(跨站脚本攻击)
- 黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式
- 分类: 1) 反射型; 2) 持久型
- 解决方法:1) 消毒; 2) HttpOnly
- 注入攻击
- 分类: 1) SQL注入攻击; 2) OS注入攻击
- 解决方法:1) 消毒; 2) 参数绑定
- CSRF攻击(跨站点请求伪造)
- 攻击者通过跨站请求,以合法用户的身份进行非法操作
- 解决方法: 识别请求者身份:1) 表单Token; 2) 验证码; 3) Referer check
- 其他攻击方式
- Error Code,可能显示异常堆栈,从而暴露危险信息,解决方法:使用统一的500页面
- HTML注释,注释可能会暴露危险信息,解决方法:code review或者自动扫描
- 文件上传,可能上传病毒文件,解决方法:设置上传文件白名单,只允许上传指定类型的文件
- 路径遍历, 在URL中使用相对路径,遍历系统未开放的目录和文件,解决方法: 将资源文件部署在独立的服务器上,使用独立域名
信息加密技术以及密钥管理
- 单项散列加密,包括MD5、SHA等
- 对称加密, 包括DES算法、RC算法等
- 非对称加密, 包括RSA算法等
- 密钥安全管理
- 将密钥和算法放在一个独立的服务器上,甚至做成一个专用的硬件设置,对外提供加密和解密服务
- 将加解密算法放在应用系统中,密钥则放在独立服务器中,在存储时,将密钥切分成数片,分别存储在不同的介质中