第一章 大型网站架构演化
大型网站软件系统的特点
大型网站软件系统的特点
高并发、大流量
高可用
海量数据
用户分布广法、网络情况复杂
安全环境恶劣
需求快速变更、发布频繁
渐进式发展
大型网站架构演化发展历程
大型网站的技术挑战主要来自庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以 P 计的数据和面对数以亿计的用户,问题就会变得很棘手。大型网站架构主要就是解决这类问题
初始阶段的网站架构
小型网站最开始只需要一台服务器就够了,应用程序、数据库、文件等所有资源都在一台服务器上。开发就是传统的 LAPM (Linux Apache PHP Mysql)
应用服务与数据服务分离
随着用户的增多,将应用和数据分离:应用服务器(CPU)、文件服务器(硬盘)和数据库服务器(硬盘和内存)
使用缓存改善网站性能
随着数据库压力增大,不同数据的访问频率不一致,考虑使用缓存保存热点数据
网站使用缓存可以分为两种:缓存在应用服务器上的本地缓存(快,但可保存数量有限,且争夺本机内存)和缓存在专门的分布式缓存服务器上的远程缓存(可以考虑集群的形式)
使用应用服务器集群改善网站的并发处理能力
随着服务器压力增大,可考虑增加机器,使用负载均衡调度机器
数据库读写分离
虽然缓存解决了热点数据的问题,但频繁的读写同一个数据库仍会存在压力。考虑使用数据库读写分离
应用服务器写主数据库,主数据库通过主从复制将数据更新到从数据库,读数据时可以从从数据库读取
使用反向代理和CDN加速网站响应
随着用户分布的越来越广泛,不同地区用户对网站的访问也会出现差异,需要考虑加速网站访问速度。主要手段为使用 CDN 和反向代理
CDN 和反向代理的基本原理都是缓存
CDN 部署在网络提供商的机房,使用户在请求网站服务时,可以从距离自己最近的网络提供商机房获取数据
反向代理部署在网站的中心机房,当用户的数据到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器缓存着数据,则直接返回
使用分布式文件系统和分布式数据库系统
随着数据库压力再次增加,读写分离已经不能满足需求,就需要分布式数据库了。分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才会使用,通常网站采用的手段都是分库分表
使用NoSql和搜索引擎
随着数据存储和检索的复杂性,需要考虑一些非关系型数据库技术和非数据库查询技术
业务拆分
将一个网站拆分到不同的应用,每个应用独立部署维护
分布式服务
系统差异进行拆分,业务相同进行聚合
大型网站架构演化的价值观
大型网站架构技术的核心价值是随网站所需灵活应付
驱动大型网站技术发展的核心力量是网站的业务发展
网站架构设计误区
一味追随大公司的解决方案
为了技术而技术
企图用技术解决所有问题
第二章 大型网站架构模式
什么是模式
每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复工作
网站架构模式
分层
分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对单一的职责,然后通过上层对下层的依赖和调用组成一个完整的系统
网络的七层通信协议是一种分层,计算机的硬件、操作系统、应用软件也是一种分层。大型网站架构中也采用分层结构
大型网站架构将网站软件系统分为应用层、服务层、数据层
应用层:负责具体业务和视图展示,如网站首页及搜索输入和结果展示
服务层:为应用层提供服务支持,如用户管理服务,购物车服务
数据层:提供数据存储访问服务,如数据库、缓存、文件、搜索引擎等
进行分层时也面临一些挑战
需要合理规划层次边界和接口
开发时,严格遵循分层架构的约束
禁止跨层次调用,如应用层直接访问数据层
禁止逆向调用,如服务层调用应用层
分割
分割是将系统在纵向维度进行分割,是将不同的功能和服务分割开,包装成高内聚低耦合的模块单元
例如对应用层的切割,可以将购物,讨论,搜索,广告分割成不同应用,由独立团队负责,部署在不同的服务器上
分布式
对大型网站,分层和分割是为了切分后的模块便于分布式部署
分布式部署的缺点
分布式意味着调用必须通过网络,网络性能会有影响
分布式意味着服务的增多,宕机概率的提升,网站可用性变差
分布式意味着保持数据的一致性变难
分布式意味着维护多个服务的困难
分布式方案
分布式应用和服务:应用的拆分和聚合
分布式静态资源:JS、CSS、Logo、图片等静态资源采用独立域名,独立部署。即动静分离
分布式数据和存储:NoSql
分布式计算:大数据等
分布式配置
分布式锁
分布式文件系统
集群
将多台服务器部署相同应用构成一个集群,由负载均衡提供统一服务
缓存
缓存常用手段
CDN
反向代理
本地缓存
分布式缓存
缓存的使用条件
数据访问热点不均衡
数据时效不一致
缓存的功能
加快数据的访问
减轻后端应用和数据存储的负载压力
异步
异步是降低系统耦合性的重要手段,单一服务可以使用多线程共享内存队列的方式实现;分布式可以使用分布式消息队列实现
异步消息队列特性
提供系统可用性
加快网站响应速度
消除并发访问高峰
冗余
通过冗余实现服务的高可用,冗余需要有服务器冗余,数据冗余等
数据冗余又包含冷备份(定期备份)和热备份(同步备份)
自动化
自动化发布
自动化代码管理
自动化测试
自动化安全检测
自动化部署
自动化监控
自动化告警
自动化失效转移
自动化失效恢复
自动化降级
自动化分配资源
安全
通过密码/手机验证码进行身份校验
敏感数据加密,敏感资源过滤
使用验证码防止机器人对网络资源供给
使用编码转化防止 SQL 注入,XSS 攻击
交易操作和交易信息进行风险控制
架构模式在微博新浪的应用
第三章 大型网站核心架构要素
软件架构的定义
有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计
性能
浏览器端:浏览器缓存、使用页面压缩、合理布局页面、减少cookie等
网络方面:CDN 、反向代理
应用服务器端:本地缓存、分布式缓存、异步、集群等
代码层面:多线程,管理内存等
数据库服务器端:索引、缓存、SQL优化等
可用性
冗余
保证软件开发过程的质量
预发布验证
自动化测试
自动化发布
灰度发布等
伸缩性
服务器的横向扩缩
扩展性
事件驱动架构:消息队列
分布式服务:服务的拆分和聚合
安全性
保护网站不受恶意访问和攻击
保护网站的重要数据不被窃取
第四章 瞬时相应:网站的高性能架构
网站性能测试
不同视角下的网站性能
用户视角:浏览器上网页响应快慢
开发人员:程序本身及其相关子系统的性能,包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等技术指标
运维人员:基础设施性能和资源利用率,包括网络运营商的带宽能力、服务器的硬件配置、数据中心网络架构、服务器和网络带宽的资源利用率
性能测试指标
响应时间
并发数
吞吐量:单位时间内系统处理的请求数字。如:TPS(每秒事务数)、HPS(每秒http请求数)、QPS(每秒查询数)
性能计数器:系统负载、对象和线程数、内存使用、CPU使用、磁盘和网络I/O
性能测试方法
性能测试
负载测试
压力测试
稳定性测试
性能测试报告
是否满足系统设计和业务需求、系统最大负载能力、系统最大压力承受能力等
性能优化策略
性能分析
检查请求处理的各个环节的日志,分析哪个环节的响应时间不合理超过预期
检查监控数据,分析影响性能的主要因素是内存、磁盘、网络、CPU 还是代码问题或者架构设计问题
性能优化
Web前端性能测试
应用服务器性能测试
存储性能优化
Web前端性能优化
浏览器访问优化
减少 http 请求:合并 CSS、合并 JS、合并图片
使用浏览器缓存
启用压缩
CSS 尽量放在页面最上面,JS 尽量放在页面最下面
减少 cookie 传输
CDN 加速
反向代理
应用服务器性能优化
分布式缓存
网站性能优化第一定律;优先使用缓存优化性能
缓存的原理
合理使用缓存
频繁修改的数据
没有热点访问的数据
数据不一致与脏读
缓存可用性
缓存预热:项目启动前提前加载热点缓存
缓存穿透:持续高并发访问缓存中不存在的数据造成访问直接到达数据库,建议不存在的数据缓存起来(置为null)
分布式缓存架构
memcached
异步操作
使用集群
代码优化
多线程
资源服用:单例和线程池
数据结构
垃圾回收
存储性能优化
略~
第五章 万无一失:网站的高可用架构
网站可用性的度量与考核
网站可用性度量
网站不可用时间(故障时间)=故障修复时间点-故障发现(报告)时间
网站年度可用性指标=(1-网站不可用时间/年度总时间)*100%
网站可用性考核
高可用的网站架构
目的:保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问
手段:数据和服务的冗余备份及失效转移
高可用的应用
通过负载均衡进行无状态服务的失效转移
应用服务器集群的Session管理
Session管理
Session绑定
利用Cookie记录Session
Session服务器
高可用的服务
分级管理
超时设置
异步调用
服务降级
幂等性设计
高可用的数据
CAP原理
高可用的层面
数据持久性
数据可访问性
数据一致性
数据强一致性
数据用户一致
数据最终一致
CAP 原理认为:一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Patition Tolerance)三个条件
数据备份
冷备
优势:简单、廉价、成本技术难度低
缺点:不能保证数据最终一致性
热备
异步热备方式:多份数据副本的写入操作异步完成
同步热备方式:多份数据副本的写入操作同步完成
失效转移
失效确认
心跳检测
应用程序访问失败报告
访问转移
数据恢复
高可用网站的软件质量保证
网站发布
自动化测试
预发布验证
代码控制
自动化发布
灰度发布
网站运行监控
监控数据采集
用户行为日志收集:服务端日志收集,客户端浏览器日志收集
服务器性能监控
运行数据报告
监控管理
系统报警
失效转移
自动优雅降级
第六章 永无止境:网站的伸缩性架构
网站架构的伸缩性设计
不同功能进行物理分离实现伸缩
单一服务器 => 数据库从应用服务器分离 => 缓存从应用服务器分离 => 静态资源从应用服务器分离
纵向分离:网站具体产品,可复用业务服务,基础技术服务,数据库
横向分离:网站前台,卖家前台,买家后台,交易论坛
单一功能通过集群规模实现伸缩
应用服务器集群的伸缩性设计
HTTP重定向负载均衡
优点:简单
缺点:需要两次请求才能完成一次访问;重定向服务器压力大
DNS域名解析负载均衡
优点:将负载均衡的工作交给了DNS服务器,省去了管理的麻烦
缺点:记录的添加与修改是需要一定时间才能够生效的(因为DNS缓存了A记录)。一旦有一台服务器坏了需要下线,即使修改了A记录,要使其生效也需要较长的时间,这段时间,DNS任然会将域名解析到已下线的服务器上,最终导致用户访问失败;不能按需分配负载,DNS并不知道各服务器的真实负载情况,所以负载效果不是很好
实际:在实际的项目部署,我们一般会将部分服务器使用 DNS 解析,利用域名解析作为第一级负载均衡.再在服务器中使用 NGINX 负载均衡作为第二级负载均衡
反向代理负载均衡
优点:简单
缺点:反向代理服务器压力大
IP负载均衡
数据链路层负载均衡
大型网站应用最广
负载均衡算法
轮询
加权轮询
随机
最少连接
源地址散列-hash
分布式缓存集群的伸缩性设计
Memcached分布式缓存集群的访问模型
Memcached分布式缓存集群的伸缩性挑战
分布式缓存的一致性Hash算法
数据存储服务器集群的伸缩性设计
关系数据库集群的伸缩性设计
NOsql数据库的伸缩性设计
第七章 随需应变:网站的可扩展架构
构建可扩展的网站架构
利用模块化实现低耦合
利用分布式消息队列降低系统耦合性
事件驱动架构:通过低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块
分布式消息队列
利用分布式服务打造可复用的业务平台
web service与企业级分布式服务
大型网站分布式服务的需求与特点
分布式服务框架设计
可扩展的数据结构
利用开发平台建设网站生态圈
第八章 固若金汤:网站的安全架构
道高一尺魔高一丈的网站应用攻击与防御
XSS攻击
攻击:即跨站点脚本攻击,指通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种方式
防御:内容过滤或消毒;禁止页面JS访问带有HttpOnly属性的cookie
注入攻击
攻击
SQL注入
攻击
开源软件的数据库表结构公开的
业务sql执行时错误信息的回显
盲猜
防御
消毒/过滤
参数绑定
OS注入
CSRF攻击
攻击:即跨站点请求伪造,利用浏览器中的cookie或者session盗取用户的身份,进行攻击
防御:表单Token;验证码;referer check
其他攻击和漏洞
error code
html注释
文件上传
路径遍历
Web应用防火墙
网站安全漏洞扫描
信息加密技术与密钥安全管理
单项散列加密:对不同长度的信息进行散列计算得到固定长度输出,过程是单向的,无法反向解密
对称加密:加密解密使用同一个密钥。即可以加解密
非对称加密:加密解密使用不同的密钥。公钥加密的信息使用私钥解开,私钥加秘的信息使用公钥解开
密钥安全管理:
信息过滤与反垃圾
文本匹配
分类算法
黑名单
电子商务风险控制
风险
账户风险
卖家风险
买家风险
交易风险
风控
规则引擎
统计模型
第十三章 大型网站典型故障案例分析
写日志也会引发故障
现象:日志塞满服务器
经验教训
应用程序的日志输出配置和第三方组件日志输出要分别配置
检查 log 配置文件,日志输出级别至少为 warn,并检查 log 输出代码调用,调用级别要符合其真实级别
关闭开源第三方组件不合理的日志输出
高并发访问数据库引发的故障
现象:SQL 频繁执行
经验教训
尽量少的直接访问数据库
应用缓存或搜索引擎
高并发情况下锁引发的故障
现象:服务器不定时的超时响应
经验教训
使用锁要谨慎
缓存引发的故障
现象:数据库服务器负载暴增最后服务器瘫痪
经验教训
认真对待缓存服务器
应用启动不同步引发的故障
现象:应用发布后服务器崩溃
经验教训
后台服务启动好后再启动前台服务器
大文件读写独占磁盘引发的故障
现象:浏览器显示服务超时
经验教训
图片等小文件尽量不要和大文件一起存储,需要根据文件大小类型用途分别管理
滥用生产环境引发的故障
现象:内部网络访问延迟
经验教训
访问生产要规范
不规范的流程引发的故障
现象:测试代码提交到生产,服务不可用
经验教训
代码提交前做 diff。确认代码正确性,SQL 也是如此
不好的编程习惯引发的故障
现象:前端报错
经验教训
不能确定对象是否为空时,就做空指针判断
代码尽量规范
系统报警
安全架构
Web攻击
数据保护
数据中心机房架构
机房架构
机柜架构
服务器架构