大型网站技术架构02 网站的高性能架构、网站的可用性架构
大型网站核心架构要素
1. 性能
2. 可用性
3. 伸缩性
4. 扩展性
5. 安全性
瞬时响应:网站的高性能架构
1. 网站性能测试:
1). 不同视角下的网站性能
a. 用户视角的网站性能:用户计算机,网站服务器通信时间,网站服务器处理时间,用户浏览器解析时间等。
b. 开发人员视角的网站性能:
c. 运维人员视角的网站性能:优化主干网,利用虚拟化技术优化资源利用等
2). 性能测试指标
a. 响应时间:单个请求时间不好计算,可以通过重复执行一万次,测试一万次执行需要的总响应时间之和,然后除以一万,得到单次请求的响应时间。
b. 并发数:指系统同时处理请求的数目,这个数字也反映了系统的负载特性。测试程序通过多线程模拟并发用户的办法来测试系统的并发能力,为了模拟真实用户行为,测试程序并不是启动多线程然后不停
地发送请求,而是在两次之间加入一个随机等待时间,这个时间被称为思考时间。
c. 吞吐量:单位时间内系统处理的请求数量,体现系统的整体处理能力。
d. 性能计数器:描述服务器或操作系统性能的一些数据指标。包括System Load、对象与线程数、内存使用、CPU使用、磁盘与网络IO等指标。这些指标也是系统监控的重要参数,对这些指标设置报警阈值,
当监控系统发现性能计数器超过阈值时,就向运维和开发人员报警,及时发现处理系统异常。
3). 性能测试方法:
a. 性能测试:以系统设计初期规划的性能指标为预期目标,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到系能逾期。
b. 负载测试:对系统不断地增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临界值,如某种资源已经呈饱和状态,这时继续对系统施加压力,系统的处理能力不但不能提高,反而下降。
c. 压力测试:超过安全负载的情况下,对系统继续施加压力,直到系统崩溃或不能再处理任何请求,以此获得系统最大压力承受能力。
e. 稳定性测试:被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,是系统运行一段较长时间,以此检测系统是否稳定。稳定性测试硬不均匀地对系统施加压力。
f. 通过测试得出:网站日常运行区间,系统的最大负载点,系统的崩溃点
4). 性能测试报告:应包括:并发数,响应时间,TPS(每秒事务数),错误率(%),Load,内存(GB),备注
5). 性能优化策略
a. 性能分析:检查请求处理的各个环节的日志,分析哪个环节响应时间不合理、超过预期;然后检查监控数据,分析影响能力的主要因素是内存、磁盘、网络、还是CPU,是代码问题还是架构设计不合理,或
系统资源不足。
b. 性能优化
2. Web前端性能优化
1). 浏览器访问优化:
a. 减少http请求:合并CSS,合并JS将浏览器需要的JS,CSS合并成一个文件。图片由多张合成一张。
b. 使用浏览器缓存:缓存静态资源。在某些时候,静态资源变换需要及时应用到客户端浏览器,可以通过修改文件名实现。静态资源多的时候,考虑逐量更新。
c. 启用压缩
d. CSS放在页面最上面、JavaScript放在页面最下面:如果页面解析时就需要用到JS,这时放在底部就不合适了。
e. 减少Cookie传输
2). CDN加速:即内容分发网络,部署在距离终端用户最近的网络服务商,用户的网络请求总是先到达他的网络服务器商那里,在这里缓存网站的一些静态资源(较少变化的数据)。可以就近以最快的速度返回给用户,
如视频网站和门户网站会将用户访问量最大的热点内容缓存在CDN。
3). 反向代理:反向带来属于网站前端架构的一部分,部署在网站的前端,当用户请求到达网站的数据中心时,最先访问到的就是反向代理服务器,这里缓存网站的静态资源。无需将请求继续转发给应用服务器就能
返回给用户。来自互联网的请求必须经过代理服务器,相当于在Web服务器和可能的网络攻击之间建立了一个屏障,起到保护作用。
3. 应用服务器性能优化:
1). 分布式缓存:网站性能优化的第一定律:优先考虑使用缓存优化性能。
a. 缓存的基本原理:缓存指将数据存储在相对较高访问速度的存储介质中,以供系统处理。一方面缓存访问速度快,可以减少数据访问时间,另一方面如果缓存的数据是经过计算处理得到的,那么被缓存的数据
无需重复计算即可直接使用,因此缓存还起到减少计算时间的作用。
缓存的本质是一个内存Hash表,网站数据访问通常遵循二八定律。
b. 合理使用缓存:频繁修改的数据(不适合),没有热点的访问(不适合),数据不一致与脏读(注意),缓存可用性(缓存崩溃后,数据库直面访问能否承受),缓存预热(提前将缓存数据加载出来),
缓存穿透(一个简单的对应策略是敬爱给你不存在的数据也缓存起来(其值为null))
一般来说,数据的读写比在2:1以上,即写入一次缓存,在数据更新前至少读取两次,缓存在有意义
c. 分布式缓存架构:一种是以JBoss Cache为代表的需要更新同步的分布式缓存,一种是以Memcached为代表的不互相通信的分布式缓存。
d. memcached : 简单的通信协议,丰富的客户端程序,高性能的网络通信,高效的内存管理,互不通信的服务器集群架构
2). 异步操作:使用消息队列将调用异步化,可改善网站的扩展性。事实上使用消息队列还可改善网站系统的性能。消息队列具有很好的削峰作用。
注意,由于数据写入消息队列后立刻返回给用户,数据在后续的业务校验、写数据库等操作可能失败,因此在使用消息队列进行业务异步处理后,需要适当修改业务流程进行配合。如订单提交后,订单
数据写入消息队列,不能立即返回用户订单提交成功。需要在消息队列的订单消费者进程真正处理完该订单,甚至商品出库后,再通过电子邮件或SMS消息通知用户订单成功,以免交易纠纷。
任何可以晚点做的事情都应该晚点再做。
3). 使用集群
4). 代码优化:
a. 多线程:从资源利用的角度角度看,使用多线程的原因主要有两个:IO阻塞与多CPU。启用线程数 = [任务执行时间/(任务执行时间-IO等待时间)]*CPU内核数
解决线程安全主要手段有如下几点:将对象设计成无状态对象,使用局部变量,并发访问资源时使用锁。
b. 资源复用:主要有两种模式:单例(Singleton)和对象池(Object Pool)
c. 数据结构:hash等
d. 垃圾回收
4. 存储性能优化:
1). 机械硬盘 VS 固态硬盘
2). B+树 VS LSM树
3). RAID VS HDFS
a. RAID(廉价磁盘冗余阵列)技术主要是为了改善磁盘的访问延迟,增强磁盘的可用性和容错能力。目前服务器级别的计算机都支持插入多块磁盘(8块或者更多),通过使用RAID技术,实现数据在多块磁盘上的
并发读写和数据备份。
RAID0:根据磁盘数量将数据分成N分,同时并发写入N块磁盘,使得数据整体写入速度是一块磁盘的N倍。读取时也一样,但只要有一块损坏,数据完整性就被破坏。
RAID1:数据在写入磁盘时,将一份数据同时写入两块磁盘,这样任何一块磁盘损坏都不会导致数据丢失,插入一块新磁盘就可以通过复制的方式自动修复,具有极高的可靠性。
RAID10:结合RAID0和RAID1两种方案,将所有磁盘平均分成两份,数据同时在两份磁盘写入,相当于RAID1,但是在每一份磁盘里面的N/2块磁盘上,利用RAID0技术并发访问。既提高可靠性又改善性能,
不过RAID10磁盘复用率较低。
RAID3:分N块,数据写入N-1块,校验数据写入到第N块。
RAID5:类似RAID3但校验数据螺旋式地写入所有磁盘中。避免磁盘频繁修改被写坏。
RAID6:数据写入N-2块,并螺旋式地在两块磁盘中写入校验信息。
b. 在HDFS(Hadoop 分布式文件系统)中,系统在整个存储集群的多台服务器上进行数据并发读写和备份,可以看作在服务器集群规模上实现类似RAID的功能,因此不需要磁盘RAID。
HDFS以块(Block)为单位管理文件内容,一个文件被分割成若干个Block,当应用程序写文件时,每写完一个Block,HDFS就将其复制到另外两台机器上,保证每个Block有三个副本,及时有两台服务器宕机,数据
依然可以被访问,相当于RAID1的数据复制功能。
对文件进行处理计算时,通过MapReduce并发计算任务框架,可以启动多个计算子任务,同时读取文件的多个Block,并发处理,相当于实现RAID0的并发访问。
5. 网站性能对用户而言是一种主观感受,性能优化的最终目的是改善用户的体验,是他们感觉网站很快。离开这个目的,追求技术上的所谓高性能,是舍本逐末,
没有多大意义。而用户体验的快或慢,可以通过技术手段改善,也可以通过优化交互体验改善。
万无一失:网站的可用性架构
1. 网站可用性的度量与考核:
1). 网站可用性度量:网站不可用也被称作网站故障,业界通常用多少个9来衡量网站的可用性。
2). 网站可用性考核:
2. 高可用的网站架构:网站高可用性架构设计的主要目的就是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问。实现高可用性的主要手段是数据和服务的冗余备份以及失效转移。磁盘损坏,则从备份的磁盘读取数据。
3. 高可用的应用:
1). 通过负载均衡进行无状态服务的失效转移:对于应用服务器集群,实现这种服务可用状态实时监测、自动转移失败任务的机制是负载均衡。负载均衡服务器通过心跳监测机制判断服务器是否可用。
2). 应用服务器集群的Session管理:集群环境下,Session管理主要有以下几种手段:
a. Session复制:大型网站不适合
b. Session绑定:可以利用负载均衡在源地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上。但这种方式不符合对系统高可用性的要求,因为一旦服务器宕机,Session就不存在了。很少被采用。
c. 利用Cookie记录Session:将Session记录在客户端,每次请求服务器的时候,经Session放在请求中发送给服务器,服务器处理完请求后再修改Session响应客户端。缺点:受cookie大小限制,影响性能,若浏览器关闭cookie,
无法使用等。
d. Session服务器:利用独立部署的Session服务器(集群)统一管理Session应用服务器每次读写Session时,都访问Session服务器。
这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器,然后针对这两种服务器的不同特性分别设计其架构。
对于有状态的Session服务器,一种比较简单的方法是利用分布式缓存、数据库等,在这些产品的基础上进行包装,使其符合Session的存储和访问要求。如果业务场景对Session管理有比较高的要求,比如利用Session服务集成
单点登录(SSO)、用户服务等功能,则需要开发专门的Session服务管理平台。
4. 高可用的服务:可复用的服务模块为业务产品提供基础公共服务,大型网站中这些服务通常都独立分布式部署,被具体应用远程调用。可复用的服务和应用一样,也是无状态的服务,因此可以使用类似负载均衡的失效转义策略实现
高可用服务。除此之外,具体实践中,还有以下几点高可用的服务策略:
1). 分级管理:运维上将服务器进行分级管理,核心应用和服务优先使用更好的硬件,在运维响应速度上也格外迅速。同时在服务部署上也进行必要的隔离,避免故障的连锁反应。低优先级的服务通过启动不同的线程或者部署在不同的
虚拟机上,核心服务和数据甚至要部署在不同的地址数据中心。
2). 超时设置:由于服务宕机、线程死锁等原因,可能导致应用程序对服务端的调用失去响应,进而导致用户请求长时间得不到响应,同时还占用应用程序资源,不利于及时将请求转移到正常的服务器上。
在应用程序中设置服务调用超时时间,一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或者将请求转移到提供相同服务的其他服务器上。
3). 异步调用:应用对服务的调用通过消息队列等异步方式完成。当然并不是所有服务调用都可以异步调用,对于获取用户信息这类调用,采用异步方式会延长响应时间,得不偿失。对于那些必须确认服务器调用成功才能进行下一步
的操作也不适合异步调用。
4). 服务降级:在网站访问高峰期,为了保证核心应用和功能的正常运行,需要对服务进行降级。降级有两种手段:拒绝服务及关闭服务。
拒绝服务:拒绝低优先级应用的调用,减少服务调用并发数,确保核心应用正常使用;或者随机拒绝部分请求调用,节省资源,让另一部分请求得以成功,避免要死大家一起死的惨剧。
关闭功能:关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节省系统开销,为重要的服务和功能让出资源。
5). 幂等性设计:保证服务重复调用的和调用一次产生的结果相同,即服务具有幂等性。
5. 高可用的数据:保证数据存储高可用的手段主要是数据备份和失效转移机制。数据备份是保证数据有多个副本,任意副本的失效都不会导致数据的永久丢失,从而实现数据完全的持久化。而失效转移机制则保证当前一个数据副本不可
访问时,可以快速切换访问数据的其他副本,保证系统可用。
缓存服务的高可用性:扩大缓存服务器集群规模的一个简单手段就是整个网站共享一个分布式缓存集群,单独的应用和产品不再部署自己的缓存服务器,只需要向共享缓存集群申请资源即可。
1). CAP原理:CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Partition Tolerance,系统具有跨网络分区的伸缩性)这三个条件。
高可用的数据有如下几层含义:数据持久性,数据可访问性,数据一致性
大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性(P),而在某种程度上放弃一致性。具体来说,数据一致性有分为如下几点:
数据强一致:各个副本的数据在物理存储中总是一致的
数据用户一致:各个副本可能不一致,但返回给用户的通过纠错机制等,返回给用户一个正确的数据。
数据最终一致:经过一段时间以后,数据最终会达到一致
2). 数据备份:
冷备份:优点是简单和廉价,成本和技术难度都比较低。缺点是不能保证数据最终一致性。同时由于数据落后,也不能保证数据可用性。
热备份:异步热备份和同步热备份
a. 异步热备份:指多份数据副本的写入操作异步完成,即应用程序收到数据服系统的写操作成功响应时,只写成功一份,存储系统会异步地写入其他副本。
b. 同步热备份:指多份数据副本的写入操作同步完成,即应用程序收到数据服务系统写入成功响应时,多份数据都已经写操作成功。
3). 失效转移:
a. 失效确认:两种方式,心跳检测和应用程序访问失败报告。对于应用程序的访问失败报告,控制中心还需要在一次发送心跳检测进行确认。
b. 访问转移:确认某台存储服务器宕机后,需要将数据读写访问重新路由到其他服务器上。
c. 数据恢复:必须将副本的数目恢复到系统设定值,防止再有服务器宕机。从健康的服务器复制数据,将数据副本数目恢复到设定值。
6. 高可用网站的软件质量保证:
1). 网站发布:通常通过发布脚本来完成发布。发布过程中,每次关闭的服务器都是集群中的一小部分,并在发布完成后立即可以访问,因此整个发布过程不影响用户使用。
2). 自动化测试:自动化测试工具可以一键完成系统部署,测试数据生成、测试执行、测试报告生成等全部测试过程
3). 预发布验证:沙箱测试,与真实线上环境尽量保持一致。
4). 代码控制:
a. 主干开发,分支发布:代码修改都在主干上进行,需要发布的时候,从主干拉一个分支发布,该分支即成为一个发布版本,如果该版本有bug,继续在分支上修改发布,将修改合并(merge)回主干,直到下次主干发布。
b. 分支开发,主干发布:任何修改都不能在主干上直接运行,需要开发一份新功能或者修复一个bug时,从主干拉一份分支进行开发,开发完成且通过测试后,合并回主干,然后从主干进行发布,主干上的代码永远是最新
发布的版本。
这两种方式各有优缺点。主干开发,分支发布,主干代码反应目前整个应用的状态,一目了然,便于管理和控制,也利于持续集成。分支开发,主干发布方式,各个分支独立进行,互不干扰,可以使不同发布周期的开发
在同一应用中进行。
5). 自动化发布:人干预越少,自动化程度越高,引入故障的可能性就越小,火车准点到达,大家按时下班的可能性就越大。
6). 灰度发布:应用发布成功后,仍然可能会发现因为软件问题而引入的故障,这时候就需要做发布回滚,即卸载刚刚发布的软件,将上一个版本恢复。为应对这种局面,大型网站会使用灰度发布模式,将集群服务器分若干部分,
每天只发布一部分。
灰度发布,也常用于用户测试,即在部分服务器上发布新版本,然后监控用户操作行为,收集用户体验报告。比较用户对两种版本的满意度,以确定最终发布的版本。这种手段称为AB测试。
7. 网站运行监控:不允许没有监控的系统上线。
1). 监控数据采集
a. 用户行为日志收集:用户行为日志指用户在浏览器上所做的所有操作以及所在的操作系统环境,包括:用户操作系统与浏览器版本,IP地址、页面访问路径、页面停留时间等。这些数据对统计网站的PV/UV指标、分析用户行为、
优化网站设计、个性化营销与推荐等非常重要。
用户行为日志收集手段有两种:
a1. 服务器端日志收集
a2. 客户端浏览器日志收集:利用页面嵌入JS脚本收集用户真实的操作行为,因此比服务器日志收集更加准确。缺点是比较麻烦。
此外,大型网站的用户日志数量惊人,数据存储和计算压力大,目前许多网络逐步开发基于实时计算框架Storm的日志统计与分析工具。
b. 服务器性能监控:收集服务器性能指标,如系统Load、内存占用、磁盘IO、网络IO等尽早作出故障预警,及时判断应用状况,防患于未然,将故障扼杀在萌芽时期非常重要。
目前网站使用比较广泛的开源性能监控工具是Ganglia,它支持大规模服务器集群,并支持以图形的方式在浏览器展示实时性能曲线。
c. 运行数据报告:网站还需要监控一些与具体业务场景相关的技术与业务指标,比如缓冲命中率、平均响应延迟时间、每分钟发送邮件数目、待处理的任务总数等。
2). 监控管理:监控数据采集后,除了用作系统性能评估、集群规模伸缩性预测等,还可以根据实时监控数据进行风险预警,并对服务器进行失效转移,自动负载调整,最大化利用集群所有机器的资源。
a. 系统报警:监控管理系统可以配置报警阈值和制售人员的联系方式,报警方式除了邮件,即时通信工具,还可以配置手机短信,语音报警,系统报警时,工程师即使在千里之外,夜里睡觉也能被及时通知,迅速响应。
b. 失效转移:除了应用程序访问失败时进行失效转移,监控系统还可以在发现故障的情况下主动通知应用,进行失效转移
c. 自动优雅降级:优雅降级是指网站为了应付突然爆发的访问高峰,主动关闭部分功能,释放部分系统资源,保证网站核心功能正常访问的一个手段。