大型网站技术架构笔记
大型网站架构演化
特点:
- 高并发、大流量
- 高可用
- 海量数据
- 用户分布广泛、网络情况复杂
- 安全环境恶劣
- 需求快速变更、发布频繁
- 渐进式开发
演化发展历程
0. 演变原因
- 在现有架构下,我们来看看数据存储的瓶颈是什么?
- 数据量的总大小 一个机器放不下
- 数据的索引(B+ Tree)一个机器的内存放不下
- 访问量(读写混合)一个实例不能承受
- 只有当以上3件事情任何一件或多件满足时,我们才需要考虑往下一级演变。
1. 初始阶段:
- 应用程序、数据库、文件都在一台服务器,如常用的Linux+PHP+Apache+Mysql
2. 应用服务和数据库分离
- 原因:性能变差、存储空间不足
- 三台服务器:应用服务器(运算能力:CPU)、文件服务器(更大的存储)和数据库服务器(更大的存储和内存
3. 使用缓存改善
- 原因:数据库访问压力太大; 数据访问遵循2-8定律
- 将访问多的20%的数据放在缓存上,可分为应用服务器端的本地缓存和分布式的远端缓存
4. 应用服务器集群
- 原因:单一服务器处理的请求链接成为瓶颈
- 使用应用服务器集群,使用反向代理实现负载均衡、可用性监测、可伸缩的实现
5. 数据库读写分离
- 原因:使用缓存后,仍有部分读操作和全部写操作要访问数据库,随着规模的增大,这些操作造成数据库瓶颈
- 数据库进行主从备份和读写分离
6. 使用反向代理和CDN加速网站响应
- 原因:加速网站访问速度
- CDN: 部署到客户端最近的网络提供商的机房,用户可从自己最近的网络提供商获取数据,多用于静态内容如CSS、图片等
- 反向代理:一般代理都是在客户的浏览器端,而此处的代理是在网站端。 用户请求先通过反向代理,反向代理如果缓存有用户需要的资源则立刻返回,否则调用相应服务器
7. 使用分布式文件系统
- 原因:业务需求继续增大
8. 使用分布式数据库
- 分库:
- 分表:单表数据规模非常庞大时
9. 使用NoSQL和搜索引擎
- 特点:数据存储和检索越来越复杂
- NoSQL对可伸缩的分布式特性有很好的支持
10. 业务拆分
- 将网站拆分成多个应用,每个应用独立维护
11. 分布式服务
- 将共有业务(用户管理、商品管理等)提取出来独立部署,上层业务复用这些业务完成具体操作
大型网站架构模式
网站架构模式
分层
- 将系统分成MVC层,对C进一步分成service层和Dao层
- 注意:定义好层次边界和接口
- 作用:便于合作开发和维护;方便分离部署
分割
- 对业务进行拆分,彼此之间低耦合,然后部署到单独的应用服务器上
分布式
分层和分割的主要目的就是为了切分后的模块便于分布式部署
常用方案有:
- 1. 分布式应用与服务:改善性能和复用
- 2. 分布式静态资源:如JS,CSS独立部署并有独立的域名
- 3. 分布式数据和存储:对传统数据库使用分布式、采用NoSQL
- 4. 分布式计算:MapReduce
集群
- 在多个机器上部署单一模块,提供扩展性、有效性、负载均衡的处理
缓存
- 条件:某些数据被频繁访问;数据在某个时间段内有效,不会很快过期
- 有以下方式:
- CDN:离用户最近,静态资源
- 反向代理:网站的前段,静态资源等
- 本地缓存:应用服务器本机
- 分布式缓存
异步
- 使用消息队列实现,单一应用服务器使用多线程之间的消息队列实现异步;分布式环境中使用分布式的消息队列实现异步
- 好处:降低耦合;加快响应速度;消除并发访问高峰
冗余
- 实现7*24小时服务,提高可用性
- 服务器集群实现; 数据库的冷、热备份
自动化
- 发布过程:自动化代码管理、自动化测试、自动化部署、自动化安全检测
- 运行过程:自动化监控、自动化报警、自动化失效转移和回复、自动化降级
安全
- 身份认证: 密码和手机校验码
- 加密:登录、交易和存储的敏感数据
- 验证码:机器人程序攻击网站
- 编码转换:XSS攻击和Sql注入
- 过滤:垃圾信息和敏感信息
- 风险控制: 对交易转账等重要操作根据交易模式和交易信息进行
大型网站核心架构要素
性能
定义:用户访问的快慢
评价指标:响应时间,TPS,系统性能计数器
手段:
- 1. 浏览器端:页面压缩、浏览器缓存、合理布局页面、减少cookie传输、CDN、CSS放在上面和js放在最下边
- 2. 应用服务器端:反向代理服务器、缓存、异步请求、集群
- 3. 代码层:多线程、改善内存管理
- 4. 数据库端:索引、缓存、SQL优化、主从备份和读写分离、NoSQL数据库
可用性
定义:可以访问的时间
评价指标:几个9,如99.99%
手段:
- 1. 冗余(应用服务器集群、数据库备份)
- 2. 软件质量:预发布验证、自动化测试、自动化发布、灰度发布
伸缩性
定义:通过向集群中加入服务器提高并发访问和数据存储需求
评价指标:是否容易添加新的服务器;新的服务器能否提供无差别服务;服务器数量是否有限制
手段:
- 1. 应用服务器集群:服务器上不保存数据(无状态)+合适的负载均衡设备
- 2. 缓存集群:改进缓存路由算法:hash环
- 3. 数据库集群:路由分区将部署有多个数据库的服务器组成一个集群; NoSQL数据库天生比较好
扩展性
定义:快速响应需求变化
评价指标:增加新业务,是否对现有产品透明无影响
手段:
- 1. 事件驱动:消息队列实现
- 2. 分布式服务:业务通过分布式框架调用可复用服务
安全性
定义:现存和潜在攻击手段的应对策略
瞬时响应:网站的高性能架构
网站性能测试
1. 不同视角的网站性能
1)用户视角
- 浏览器和服务器通信时间+处理时间+浏览器解析响应数据的时间
2)开发人员视角
- 应用程序本身和子系统的性能,有 响应时间、吞吐量、并发处理能力、系统稳定性等指标
3)运维人员视角
- 关注基础设施性能和资源利用率,如网络带宽利用率和服务器资源利用率等
- 手段:建设优化骨干网、定制的服务器、使用虚拟化技术优化资源利用率
2. 性能测试指标
响应时间:
- 执行一个操作需要的时间
- 测量方法:重复请求,如一个请求重复执行1万次,求得单次平均访问时间
并发数:
- 同时访问的请求数量
- 测量方法:模拟并发用户,在两次请求之间加入随机等待时间(思考时间)
吞吐量:
- 单位时间内处理的请求数量,TPS(每秒事务数)
- 并发小:吞吐量增加、响应时间小幅上升;并发逐渐增加:吞吐量下降、响应时间快速上升;并发达到崩溃点:吞吐量为0,不响应
性能计数器
- 描述服务器和操作系统性能的数据指标,如System Load(进程数和CPU数)、内存和CPU使用、对象与线程数
3. 性能测试方法
- 性能测试:以系统规划初期的指标测试
- 负载测试:增加并发请求,直到多项性能指标达到临界值
- 压力测试:直到系统崩溃
- 稳定性测试:特定软硬件条件下,给系统加载一定业务压力,使系统运行一段时间
4. 性能优化策略
- 性能分析: 检查各环节日志——》检查监控数据,关注内存、磁盘、网络、CPU——》确定是代码问题、架构设计还是系统资源不足
Web前段性能优化
浏览器访问优化
1. 减少http请求
- 合并javascript css、图片(如果每张独有不同的超链接,可通过css偏移响应鼠标点击操作,构造不同的URL)。
2. 使用浏览器缓存
- 设置http头中的Cache-Control和Expires设定浏览器缓存
- 静态文件变化后:改变js文件名并更新html文件中的引用
- 更新静态资源时,采用批量更新的方法,比如更新10个图标文件,应一个文件一个文件逐步更新,并有一定时间间隔
3. 启用压缩
- 可对html css javaScript启动GZip压缩,但会对服务器产生压力
- 需要在 通信和服务器资源间权衡考虑
4. CSS放在页面最上面,JavaScript放在最下面
- 浏览器会在下载完全部CSS后才进行页面渲染,最好是把CSS放在页面上边
- 浏览器在加载Js后立刻执行,有可能阻塞整个页面,因此js放在下面,但如果页面解析时就要用到JavaScript的,放在下面就不太合适了
5. 减少cookie传输
- 静态资源使用独立域名,避免发送cookie
- 哪些数据需要写入cookie要慎重考虑
CDN加速
- 用于对静态资源的代理
反向代理
- 部署在应用服务器前边,实现 安全过滤、缓存加速web请求、负载均衡
- 应用服务器性能优化
主要手段有缓存、集群和异步
分布式缓存
- 网站优化第一定律:优先考虑缓存优化
- 缓存实际是内存的hash表
1. 合理使用缓存:
- 1)频繁修改的数据:读写比在2:1以上
- 2)没有热点的访问
- 3)数据不一致和脏读:设置失效时间、数据更新时立即更新缓存
- 4)缓存可用性
- 5)缓存预热:新缓存上没数据
- 6)缓存穿透:持续高并发地请求某个不存在的数据,会对数据库造成很大压力
2. 分布式缓存架构
集群
异步
- 使用消息队列:减少响应延迟、平滑并发访问波动;
- 需要对返回状态做特殊处理,如订单提交(等待消费者处理完后才显示成功)等
代码优化
1. 多线程
- 使用原因:IO阻塞会释放CPU; 多CPU每个对应一个
- 多少线程: 启动线程数=【任务执行时间/(任务执行时间-IO等待时间)】*CPU数
- 线程安全问题:对象是无状态的;使用threadLocal 方法内对象;并发访问资源时加锁
2. 资源复用
- 开销很大的资源,如数据库连接、网络连接、线程、复杂对象。有两种模式:单例和对象池
3. 数据结构
- 字符串Hash散列算法:Time33算法: hash(i)=hash(i-1)*33+str[i]
- 相似的字符串hash值区别很大: MD5算法
4. 垃圾回收
- 有助于程序优化和参数调优,分为stack和heap,堆空间分为Young Generation(Eden from to)和Old Generation,新建对象在Eden,当Eden满时,复制到from;Eden又满了,将Eden和from——》to,下次Eden+to——》from,young都满了就放到old,如果都满了就触发Full GC(时间比较长)
- 合理设置young 和 old大小,尽量减少Full GC
存储性能优化
- 机械硬盘 vs 固态硬盘
- B+树 vs LSM树
- RAID vs HDFS
- 万无一失:网站的高可用性架构
- 可用性的度量和考核
- 可用性度量: 几个9,如99.99%
- 可用性考核(对工程师的考核): 故障时间*故障权重
高可用的网站架构
- 企业级采用昂贵的软硬件,如IOE;互联网更多是PC级服务器、开源的数据库和操作系统
- 主要手段:数据和服务的冗余备份和失效转移。
高可用的应用
- 1. 无状态应用服务器
- 采用负载均衡软件,一般都提供:心跳检测可用性;失效转移、负载均衡
2. 有状态的应用服务器
- 1)session复制:当服务器集群规模下的时候可用。通过开启web容器的session复制功能,让每台服务器上都有用户session信息。 应用在集群规模小的情况下。
- 2)session绑定:使用负载均衡软件的源地址hash算法,保证同一IP的处理总在一台服务器上。但使用较少,主要是可用性的问题,如果该机器done了,该用户的session会丢失
- 3)cookie记录session:1)cookie大小限制;2)每次都要传输;3)关闭cookie访问不正常;4)简单易用;5)支持应用服务器的线性伸缩。 大部分网站或多或少使用。
- 4)session服务器: 可用性高,伸缩性好,性能也不错,信息大小又没限制。 将服务器中session都放到独立的session服务器统一管理,每次读写session时,都通过session服务器。通过对分布式缓存、数据库基础上包装实现。
高可用的服务
- 1. 分级管理: 对不同的功能模块进行分级,对于高优先级使用好的硬件,更快的相应速度;等访问量大时,可关闭低优先级功能
- 2. 超时设置: 设置调用的超时时间,当服务不可用或超时后,通信框架报出异常,根据调度策略转移到其他服务器
- 3. 异步调用:消息队列
- 4. 服务降级:访问高峰期,拒绝低优先级服务
- 5. 冥等性设计:请求重新发送时,保证统一请求重复调用和一次调用结果相同,比如转账(使用交易编号)
高可用的数据
- 1. 冷备: 廉价; 不能保证数据一致性;可用来定期备份
- 2. 异步热备:只写成功一份,其他之间复制
- 3. 同步热备:同时向多个副本中写入
- 4. 失效转移:失效确认(心跳检测和访问异常)——》访问转移——》数据恢复
- 5. 库表散列: 不同业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。
高可用网站的软件质量保证
1. 网站发布
- 每次关闭服务器集群中的一小部分,发布完后立刻可以访问。
- 使用发布脚本实现
2. 自动化测试
- Selenium 自动化测试技术
3. 预发布验证
4. 代码控制
- 要求:发布版本和开发版本互不影响
- 主干开发、分支发布:发布时主干出一个branch,如果该版本有bug,在分支上修改发布,并将修改merge回主干
5. 自动化发布
6. 灰度发布
- 每天只发布一部分服务器,观察运行稳定没有故障
网站运行监控
1. 数据采集
- 用户行为日志收集:服务器端(web服务器)、客户端(javascript)
性能监控
运行数据报告
- 统计:基于实时计算框架Storm的日志统计和分析工具
2. 监控管理
- 系统报警
- 主动失效转移
- 自动优雅降级
- 永无止境:网站的伸缩架构
- 伸缩性:当访问量增加时,通过增加资源(服务器)可以提高吞吐率
- 伸缩性设计是复杂的、没有通用的、完美的解决方案
网站架构
根据功能进行物理分离实现伸缩
一台服务器——》数据库分离——》缓存分离——》静态资源从应用服务器分离
纵向分离(按层分割):网络具体产品--可复用业务服务--基础技术服务--数据库
横向分离(业务分割):网站前台--买家前台--卖家后台
单一功能通过集群实现伸缩
条件:当随着访问量增大,即使分离到最小粒度的独立部署,单一服务器也不能满足需要
应用服务器集群
1. 如果是无状态的,可以使用负载均衡(请求分发,服务器可用性监测)
2. 负载均衡实现技术有:
- 1. http重定向: 使用http request将用户请求重新定向到处理服务器,优点是简单;缺点是两次请求才能完成一次访问,性能较差。重定向服务器可能成为系统瓶颈。 http302会被搜索引擎判定为作弊。 实际使用中不多见
- 2. dns域名解析:在DNS中实现负载均衡。优点是负载均衡给了DNS实现简单。可以解析到用户最近的服务器地址;缺点是当下线了某台服务器不能立即反应。 实际中大型网站使用DNS作为第一级负载均衡,到同样提供负载均衡的内部服务器
- 3. 反向代理: 反向代理服务器提供缓存资源、负载均衡的功能,需要部署双网卡和双ip,优点是 和反向代理功能一起部署比较简单。缺点是反向代理服务器是所有请求和响应的中转站,性能可能成为瓶颈
- 4. IP负载均衡:负载均衡服务器修改数据包中的目的IP地址实现。优点较反向代理有更好的处理性能;缺点是所有请求都经过,数据吞吐量受限于网卡带宽
- 5. 数据链路层负载均衡:修改mac地址实现。使用最广,linux平台使用LVS(Linux Virtual Server)
3. 负载均衡算法
- 轮询:请求依次分发
- 加权轮询:根据服务器的硬件情况加权
- 随机:好的随机数本身就很均衡,如果硬件配置不同,可使用加权随机
- 最少链接:记录每个服务器的连接数,新的请求分配到最少的
- 源地址散列:对IP进行散列,使得该IP的上下文信息存储在这台服务器上,实现会话粘滞
分布式缓存
- 1. 目标: 新加入的缓存使得已缓存的数据尽可能能被访问到
- 2. memchached 分布式缓存集群,其中路由算法很重要:
- 1. 余数hash: 缓存数据hashcode/服务器数目。 但添加新的缓存服务器就麻烦了,解决方案是 使用虚拟节点的一致性hash环
数据存储服务器
1. 目标:相对于缓存,对数据的持久性(能存到硬盘)和可用性(能访问到数据)要求更高
2. 关系型数据库
- 数据库复制: 主从读写分离; 分库(不同表在不同数据库集群,缺点是不能进行跨库join); 分表(产品有Amoeba和Cobar,Cobar可与mysql集群使用)
- 伸缩的实现:Corba的服务器使用负载均衡;Mysql(Cobar利用Mysql的数据同步功能进行数据迁移)
- 无法执行跨库Join和事务
- 避免事务或利用事务补偿机制(分布式事务)代替数据库事务;分解数据访问逻辑避免JOIN操作
- 支持JOIN的,如GreenPlum,但延迟比较大
3. NoSql数据库
Apache 的HBase,依赖于可分裂的HRegion(数据块)和HDFS(分布式文件系统)。使用者无需处理
随需应变:网站的可扩展架构
扩展性: 对现有系统影响最小情况下,可以加功能,符合开闭原则
构建可扩展的网站架构
软件架构师最大的价值不是掌握多少先进技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力,这些子模块包括横向模块和纵向模块。这种能力是专业的技术和经验,对业务场景的理解,对人性的把握。
核心思想是模块化,并在此基础上,降低模块间的耦合性
主要手段是分层和分割,模块间通过分布式消息队列和分布式服务聚合
利用分布式消息队列降低耦合性
事件驱动架构
借助事件完成模块间合作,常见的是生产者消费者模式,最常用的分布式消息队列
好处是:更好的响应延迟;平缓高峰压力;
分布式消息队列
- ActiveMQ:除了实现分布式消息队列,在伸缩性(加入队列服务器)和可用性(内存队列满后,写入磁盘)也做了改善。
- 避免系统当机造成消息丢失,会把发送成功的消息存储在生产者服务器,等消息被消费者处理后才删除消息。
分布式服务
- 纵向拆分:将一个大应用拆分为多个小应用,部署为单独的web系统
- 横向拆分:将复用业务拆分后部署为分布式服务,新增业务调用这些服务
- 纵向比较简单,通过梳理业务将较少相关的业务剥离,使其成为独立的web应用。横向不仅要识别可复用的业务,设计服务接口,规范依赖关系,还需要一个完善的分布式服务管理框架。
- web service与企业级分布式服务
可整合异构系统和构件分布式系统
缺点: 臃肿的注册和发现机制;低效的xml序列化;开销相对较高的HTTP远程通信;复杂的部署和维护手段。
大型网站分布式服务的需求
服务注册和发现
服务调用
负载均衡:对热门服务如登录或商品服务,需要部署在集群上
失效转移
高效的远程通信
整合异构系统
对应用最少侵入:尽量使框架和业务独立
版本管理:提供者升级接口发布新版本服务,并同时提供旧版本服务,当请求者调用接口升级后才关闭旧版本服务。
分布式服务框架设计
开源的阿里的Dubbo
描述:
1. 消费者通过服务接口调用服务,服务接口通过代理加载服务,代理调用服务框架客户端模块,客户端包括服务提供者列表、负载均衡、失效迁移服务
2. 提供者提供服务管理容器注册服务
3. 支持多种通信协议和序列化协议,使用NIO通信框架,具有较高的网络通信性能
可扩展数据结构
无需修改表字段就可以新增字段,使用NoSql数据库
利用开放平台建立生态圈
提供更多的增值服务,将API开放被第三方开发者使用
固若金汤:网站的安全架构
网站应用攻击和防御
1. XSS攻击
跨站点脚本攻击,有两种,一种是反射性(在url中 ?),一种是持久型XSS(将恶意脚本的请求保存到数据库中,常用语论坛和博客)
防范手段: 消毒(对提交的文本进行匹配替换
2. 注入攻击
- 需要对数据库有所了解,通过开源(网站使用开源软件搭建);错误回显(从错误信息猜测表结构);盲注(猜测数据库表结构)
- 防范手段:消毒(可能注入的sql,如drop table delete from等);参数绑定(PrepareStatement, ?而不是链接字符串)
3. CSRF攻击
- 跨站点请求伪造:通过跨站请求,以合法用户身份进行非法操作
- 关键是识别请求者身份,防范手段:
- 表单token、
- 验证码(糟糕的用户体验,只在必要时使用,如支付交易);
- Referer check(检查http请求头的referer的请求来源,可用来实现图片防盗链)
4. 其他攻击和漏洞
- Error code:获得异常信息,查找系统漏洞; 防范手段:专门的错误页面
- html注释: 发布前自动扫描,去除html注释
- 文件上传:防范手段:设置上传文件白名单,只允许上传可靠的文件类型;修改文件名;使用专门的存储
- 路径遍历:在url中使用相对路径;防范手段:动态参数不包括文件路径信息;其他文件不适用静态URL访问
5. web应用防火墙
- 处理网站攻击的产品,开源的Web应用防火墙:ModSecurity
6. 网站安全漏洞扫描
- 根据内置规则,构造具有攻击性的URL请求模拟黑客攻击行为
信息加密技术和秘钥安全管理
1. 单向散列加密
不能逆转得到明文,字符串微小差别输出差别很大,不同长度输入得到固定长度的输出
常用的有MD5 SHA
用于密码加密保存、生成信息摘要
2. 对称加密
算法简单,效率高,系统开销少,适合对大量数据加密;使用同一秘钥,远程通信下如何安全交换秘钥是个难题
常用的有DES RC
用于信息需要安全交换或存储的场合,如Cookie加密、通信加密等
3. 非对称加密
用于信息安全传输、数字签名。
在实际中,常会混合使用对称加密和非对称加密。先使用非对称对秘钥进行安全传输,再使用对称进行信息加密和交换。 有时对一个数据两次使用非对称加密,可同时实现信息安全传输与数字签名的目的。
4. 秘钥安全管理
- 写到配置文件,线上和线下使用不同的
- 加密算法放在应用系统中,秘钥放在一个独立的服务器,甚至做成一个专用的硬件设施
- 秘钥分片后存储在多个服务器
信息过滤和反垃圾
1. 文本匹配
- 敏感词过滤: 正则表达式(敏感词较少、提交的文本长度较短);Trie树(敏感词较多、提交的文本长,如双数组Trie算法);多级Hash表(Trie中相同父节点的字放在Hash表中, 速度较快,浪费部分内存)
2. 分类算法
数据挖掘:分类算法, 贝叶斯算法
3. 黑名单
hash表,布隆过滤器
电子商务风险控制
1. 风险
2. 风控
- 规则引擎: 将业务规则和规则处理分开,业务规则可配置
- 统计模型:数据挖掘分类算法(当规则增加,出现规则冲突、难以维护时)
- 维基百科高性能架构
- 目标:业务简单,大部分是读操作
组成部分
- GeoDNS:将域名解析到离用户最近的服务器
- LVS:Linux的开源负载均衡服务器
- Squid:Linux的开源反向代理服务器
- Lighttpd: 开源的应用服务器,更快速,更轻量,许多网站作为图片服务器
性能优化策略
1. 前端优化
- 请求先经过GeoDNS到达地理最近的CDN服务器,如果没找到调用LVS到Squid服务器,如果缓存有则返回,否则通过LVS分发到Apache应用服务器集群。
2. 服务端优化
- 代码和数据结构(非特定)
3. 数据端优化
最主要手段是缓存,策略如下
- 1. 热点特别集中的数据缓存到应用服务器的本地缓存
- 2. 缓存数据尽可能是直接可用格式,如HTML格式
- 3. 使用缓存服务器存储session对象
4. 数据库如下优化
- 1. 更大内存
- 2. Master当机,关闭写功能,将应用切换到Slave
秒杀系统架构案例
技术挑战
- 1. 对原有业务形成冲击
- 2. 高并发下数据库、应用负载
- 3. 突然增大的服务器和网络带宽
- 4. 防止秒杀前下单
应对策略
1. 独立部署
- 和原有业务部署在不同服务器,防止高并发拖垮整个网站
2. 页面静态化
- 将商品详情、描述静态化到页面
3. 租借秒杀网络带宽
- 向运营商租借带宽
4. 动态生成随机下单页面URL
- 无法在秒杀前访问下单页面的URL:加入服务器端生成的随机数作为参数,在秒杀开始前才能得到
架构设计
1. 控制秒杀购买页面的点亮
- 秒杀商品页面加入一个javascript引用,该javascript中加入秒杀是否开始的标志和下单页面URL的随机数参数,该javascript使用随机版本号,不可被浏览器缓存
- 当秒杀开始时,生成一个新的javascript文件并被用户浏览器加载
2. 允许第一个订单提交
- 控制进入下单页面入口,只有先提交的少数用户可进入,后边的用户直接进入秒杀结束页面
架构师领导艺术
架构师角色
架构设计、软件开发
承担一些管理职能:规划产品路线、估算人力资源和时间资源
安排人员职责分工,确定计划里程碑点、指导工程师工作、过程风险评估与控制
与组内外各种角色沟通
架构师职场攻略
新员工tip
首先要做的是融入团队,和大家打成一片。等熟悉情况后,知道了水的深浅,再寻找突破口,择机而动
新员工最不需要做的就是证明自己的能力
提出问题,寻求支持
对于问题,找到谁需要对可能发生的问题负责。要解决方案被接受,就必须找到问题负责者并愿意支持他的人
提出问题tip
1. 把我的问题表述成我们的问题
2. 给上司提封闭式问题,给下属提开放式问题
给上司提问题是希望得到支持,给下属提问题是为了启发他思考
3. 指出问题而不是批评人
在合作中出现问题,告诉问题存在和紧迫性
4. 用赞同方式提出问题
我非常赞同你的方案,不过我有一个小小的建议
解决问题tip
1. 在解决我的问题前,先解决你的问题
在帮别人解决问题的过程中,熟悉了情况,解决自己的问题就得心应手了
2. 适当的逃避问题
对于不怎么靠谱的问题和方案: 这个idea很好,改天组织个会议好好讨论下
之前很早的时候了解过这本书,但是发现很多都是概念性的东西,没有意向看。
后来在微博上看到一个我比较欣赏的架构师分享这本书,说是基本上涵盖了他过去十来年的一些点,于是打算买回来看了看。发现还是挺不错的,后面的案例有的过于宽泛,但是整体还是挺不错的。
架构一词,比较飘渺,隐藏在代码的背后,似有似无。大家对于架构师这个职位也褒贬不一。大型网站不是设计出来的,而是逐步发展演化过来的。
什么是架构?
最高层次的规划,难以改变的决定,这些规划和决定奠定了事物未来发展的方向和最终的蓝图。
什么是软件架构?
有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。
关于架构师?(发现问题,寻找突破;提出问题,寻求支持;解决问题,达成绩效)
关注人而不是产品,需找一个值得共同奋斗的目标,营造一个让大家都能最大限度发挥自我价值的工作氛围;
发掘人的优秀;
当大家不再讨论架构的时候,表明架构已经融入到项目、系统和开发者中了;
成就他人,做成一个项目不但要给客户创造价值,为公司盈利,还要让项目成员获得成长;
架构师最大的价值不在于掌握了多少先进的技术,而在于将一个大系统切分为N个低耦合的子模块的能力,这些子模块包含横向的业务模块,也包含纵向的基础技术模块,这种能力一部分源自于专业的技术和经验,还有一部分源自架构师对于业务场景的理解,对人性的把握,甚至对世界的认知。
大型网站软件系统的特点
高并发、大流量(这个不用说,要不也不叫大型网站了)
高可用(用户多,所以基本是要求7*24不间断服务了)
海量数据(用户行为中产生的数据必然会很多)
用户分布广泛,网络情况复杂(这个全国各地的网络情况确实比较复杂)
安全环境恶劣(由于面向的是公众的网络,所以各种安全问题应该都会有)
需要快速变更,发布频繁(这个。。。互联网公司的节奏一直比较快)
渐进式发展(在做的过程中可能需要多次试错和迭代)
大型网站架构演化过程
初始阶段,这个阶段可能应用服务器、文件服务器、数据库所有的资源都在同一台服务器上
应用服务器和数据库服务器拆分
使用缓存改善网站的性能(貌似互联网架构中,缓存是离不开的话题了)
使用应用服务器的集群来改啥网站的并发处理能力(不过一般是同构的集群,伪集群了)
数据库读写分离(由专门的机器提供写服务,专门的机器提供读服务,如果读写比例很大,可以多态读服务器)
使用反向代理和CDN加速网站响应(这两个原理都是缓存,CDN部署在网络提供商的机房,使用户在请求网站服务时,可以在距离自己最近的机房获得数据,反向代理则部署在网站的中心机房,当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器缓存用户的请求资源,可以直接返回给用户)
使用分布式文件系统和分布式数据库系统
使用NOSQL和搜索引擎
业务拆分(这个更多的是业务层面的规划了)
分布式服务(我简单划分可以使消息系统和同步的RPC调用,消息的话是异步的解决方案,RPC的话是同步的调用方案)
大型网站架构演变的价值观
随网站所需灵活应对
主要力量是网站的业务发展
不要一味的追求大公司的解决方案,场景为王
不要为了技术而技术,脱离业务场景的技术没有意义
不要企图用技术解决所有问题
架构的模式
分层,分层是应用系统中最常见的一种架构模式,在计算机世界中无处不在,可以更好的把庞大的软件系统切分成不同的部分,便于分工合作和维护。分层中的挑战就是合理规划层次的边界和接口,严格遵守分层的约束,禁止跨层次的调用以及逆向调用。
分割,分割在纵向层面对软件进行切分。比如网购系统,在应用层,分割为交易、物流、优惠、库存等系统。
分布式,分割和分层便于切分后的模块能够便于分布式部署。分布式应用和服务、分布式文件系统、分布式数据和存储、分布式计算、分布式配置、分布式锁。
集群,多台服务器部署相同的应用构成一个集群,保证负载均衡的同时来提升系统的可用性,互相灾备。
缓存,CDN、反向代理、本地缓存、分布式缓存、数据库缓存、浏览器缓存
异步,异步架构中最典型的就是生产者和消费者模式,要解耦,就用异步,异步离不开队列,有效的利用异步,能够消除并发访问的高峰。
冗余,在集群中机器数量达到一定数量的时候,部分机器宕机会是常态,因此需要数据冗余备份,数据库定期备份称之为冷备份,主从分离实时同步称之为热备份。
自动化,发布过程自动化、代码管理自动化、自动化测试、自动化安全扫描、自动化低级bug扫描、自动化监控、自动化报警、自动化失效转移、自动化降级。
安全,互联网开放的特性注定了在安全方面提升了很大的挑战。
好的设计绝对不是模仿,不是生搬硬套一个特定的模式,而是对问题深刻理解之上的创造和创新。
架构的要素
性能,性能是网站的一个重要指标
可用性,几乎所有的网站是要求7*24可用,能够达到四个九等
伸缩性,大量用户的高并发和存储海量数据,能否进行灵活的增减机器来应对流量的变化(应用服务器、缓存服务器、关系型数据库服务器、NOSQL服务器)
扩展性,在网站增加新的业务产品时,能否可以实现对产品透明无影响,功能之间耦合小,避免牵一发动全身,目前的主要手段是事件驱动(通常利用消息队列)和分布式服务
安全性,针对现存或者潜在的各种攻击与窃密手段,能否有可靠的应对策略
网站的高性能架构
不同角度下的网站性能
用户视角,在浏览器上直观的感受到网站响应速度
开发人员视角,响应延迟、系统吞吐量、并发处理能力、系统稳定性等指标
运维人员视角,基础设施性能和资源利用率
性能测试指标
响应时间,执行一个操作需要的时间
并发数,同时处理的请求数
吞吐量,单位时间内系统处理的请求数
性能测试的方法
性能测试(一个总称)
负载测试
压力测试
稳定性测试(系统在特定硬件、软件、网络环境条件下,持续运行一段时间是否稳定)
系统的最大负载点以及系统的崩溃点
Web前端性能优化
减少Http请求(http为无状态,每次请求需要重新建立通信链路)
使用浏览器缓存(通过设置HTTP头中的Cache-Control和Expires属性)
启用压缩,服务器端对文件进行压缩,在浏览器端对文件进行解压缩
CSS放在页面最上面,js文件放在最下面(浏览器会在下载完所有的CSS之后才开始对整个页面渲染,加载JS后立即执行)
减少Cookie传输
使用CDN加速和反向代理加速
应用服务器性能优化
分布式缓存(优先使用缓存优化性能)
异步(消息队列具有很好的消峰作用,使用异步处理,将短时间的高并发产生的事务消息存储在消息队列中)
使用集群
代码优化
多线程(线程安全问题:使用无状态的对象、使用局部对象、并发访问资源添加锁)
资源复用(单例模式和对象池<对象创建比较耗时的情况下使用对象池能够提升性能>)
合理使用数据结构
JVM中GC的优化
存储系统的性能优化
合理使用缓存
频繁修改的数据不适合使用缓存
没有热点的访问,数据缓存没有意义
数据的不一致和脏读
缓存的可用性
缓存如何预热
缓存穿透
服务器集群的Session管理
Session复制
Session绑定(又称为会话粘滞,利用负载均衡的源地址Hash算法实现,是一个用户的请求总是落在一台服务器上)
利用Cookie记录Session(收到Cookie大小的限制,同时会有安全隐患)
Session服务器
如何构建高可用服务
分级管理(分组,做好资源的隔离)
超时设置(如果不知道设置多少,可以设置3S )
异步调用
服务降级
幂等性设计
数据备份
失效转移(失效确认、访问转移、数据恢复)
高可用网站的软件质量保证
自动化测试
预发布验证
自动化发布
灰度发布
网站运行监控(不允许没有监控的系统上线)
用户行为日志收集
服务端日志收集
客户端浏览器日志收集
服务器性能监控(系统Load、CPU使用率、磁盘IO、网络IO)
系统运行数据报告
系统报警
失效转移
自动化优雅降级
应用服务器集群的伸缩性设计(伸缩性设计几乎是稍微有点规模的网站的必须要求)
HTTP重定向实现负载均衡
DNS域名解析实现负载均衡
反向代理负载均衡(在HTTP协议层面,也叫应用层负载均衡)
IP负载均衡(在内核进程完成数据分发,请求进入和请求返回,都会经过负载均衡服务器)
数据链路层实现负载均衡(三角传输模式,在请求进入经过负载均衡服务器,在请求返回的时候,直接返回给用户)
负载均衡的算法
轮训(RR)
加权轮训(在轮训的基础上,按照配置的权重将请求分发)
随机
最少连接(记录每个应用服务器正在处理的连接数,根据服务器当前的资源使用情况)
源地址散列(根据请求的IP地址进行Hash计算,这样同一个IP会在同一个服务器)
分布式缓存的伸缩性设计
(上线下线机器,对于整个缓存集群的影响最小)
一致性Hash算法,先构造一个长度为0到2的32次方的整数环,根据节点名称的hash值,将缓存服务器节点放置在Hash环上。
然后根据缓存数据的数据KEY的值计算得到hash值,然后在hash环上顺时针查找距离这个key的hash值最近的缓存服务器节点,从而完成key到服务器的hash映射查找。
在具体应用中,长度为2的32次方的Hash环通常使用二叉树查找来实现,二叉树查找是查找小于查找数的最小数值,树的最右边和最左边节点相连,构成环。
有个小问题,就是新加入节点3(原来有0、1、2三个节点),只影响到节点1,也就是说一部分原来需求访问1的缓存数据现在需要访问节点3,原来的0和2不受影响,这样的话0和2的缓存数据量和压力是1和3的两倍,这种问题咋解决呢?
使用虚拟层的手段,将每台物流缓存服务器虚拟为一组虚拟缓存服务器,将虚拟服务器的hash值放置在hash环上,key在环上先找到虚拟服务器的节点,再得到物流服务器的信息,最终的结果是,新加入一台缓存服务器,将会较为均匀的影响集群中已经存在的所有服务器。例如刚才讨论的问题,新加入的节点3,对应虚拟节点为V30、V31、V32,加入到一致性Hash环中,将影响V01、V12、V13,这三个虚拟节点对应0、1、2三体物理机,这样压力就会均摊。
扩展性和伸缩性的区别
扩展性是针对系统影响最小的情况下,系统功能可持续扩展或提升的能力。
伸缩性,系统通过增加或者减少自身资源规模的方式增强或者减少计算处理事务的能力。
利用消息队列降低系统的耦合性
事件驱动架构,通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块的协作,典型的生产者消费者模式
分布式消息队列,消息队列可以简单,比如mysql作为消息队列,也可以复杂,例如ESB(企业服务总线等)
利用分布式服务来打造可复用的业务平台
webservice(通过WSDL来描述服务,通过SOAP来定义对象)
臃肿的注册和发现机制
低效的xml序列化手段
开销相对比较高的http远程通信
分布式服务的需求和特点
负载均衡(如何是TCP层面,可以做到软负载)
失效转移
高效的远程通信
整合异构系统
对应用最小侵入
服务版本管理
实时监控
服务降级
服务分组处理
服务流控处理(SLA)
按照机房等机型权重分发请求
网站的安全架构
XSS攻击
CSRF攻击
SQL注入攻击
代码可能存在安全隐患扫描
线上日志监控和安全枚举回放日志
安全漏洞扫描
信息加密技术
单向散列加密(指通过对不同输入长度的信息进行散列计算,得到固定长度的输出,这个散列的过程是单向的)
例如常见的MD5
输入的任何微小变化可能导致结果完全不同
对称加密(加密和解密使用的密钥是同一个)
特点是算法简单,加密解密效率高,系统开销小
缺点是使用同一个密钥,有安全隐患
例如DES算法和RC算法
非对称加密(加密和解密不是用一个密钥,例如RSA算法)
信息安全传输
发送者A通过公开途径获得信息接受者B的公钥,对信息进行加密,然后通过非安全的通道把密文发送给B
B得到密文之后,用自己的私钥解密,获得明文信息
数字签名 (和信息安全传输相反)
签名者用自己的私钥对信息进行加密,然后发送给对方
接收方用签名者的公钥对信息进行解密,获得明文信息,
由于私钥只有签名者拥有,信息具有不可抵赖性,具有签名的性质
常用的算法有RSA,HTTPS中传输的浏览器使用的数字证书实质上是经过权威机构认证的非对称加密的公钥
一些常见的大型网站的故障案例
写日志引发的故障
注意日志的级别
应用程序自己的日志输出配置和第三方组件的日志输出分别配置
高并发引发数据库访问的故障
数据库做好监控
如果并发特别高的页面,使用缓存,切记不要使用数据库
高并发下锁引发的故障
例如一个单例对象中多处使用了synchronized,这样所有的并发请求都要排队获得唯一的一把锁
在使用锁的时候一定要慎重啊
缓存引发的故障
缓存在提升性能的同时,在数据的一致性和系统的可运维性方面带来了很大的挑战
线上的生产环境要敬畏,不要随便操作
发布过程中要注意流程和监控,发现问题及时回滚处理
(。・v・。)