系统不可用时间(故障时间)= 故障修复时间点 - 故障发现(报告)时间点
系统年度可用性指标 = (1 - 网站不可用时间 / 年度总时间) * 100%
故障计算公式:故障分 = 故障时间(分钟) x 故障权重
故障类型 | 故障描述 |
---|---|
事故级故障 | 严重故障,系统整体不可用 |
A类故障 | 系统访问不顺畅或核心功能不可用 |
B类故障 | 非核心功能不可用,或核心功能少数用户不可用 |
C类故障 | 以上故障的其他故障 |
实现高可用架构的主要手段是数据和服务的冗余备份及失效转移,一旦某些服务器宕机,就将服务切换到其他可用的服务器上
应用层主要处理系统的业务逻辑,有时候也称为业务逻辑层,应用的一个显著特点是应用的无状态性
所谓无状态的应用是指应用服务器不保存业务的上下文信息,而根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例之间完全对等,请求提交到任意服务器,处理结果是完全一样的
负载均衡,主要使用在业务量和数据量较高的情况下,当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上,以提高整体的负载处理能力
集群环境下,Session 管理主要有以下几种手段
Session 复制是早期企业应用系统使用较多的一种服务器集群 Session 管理机制
此方案虽然简单,从本机读取 Session 信息也很快,但只能使用在集群规模比较小的情况下。当集群规模较大时,集群服务器间需要大量的通信进行 Session 复制,占用服务器和网络的大量资源,系统不堪负担。而且由于所有用户的 Session 信息在每台服务器上都有备份,在大量用户访问的情况下,甚至会出现服务器内存不够 Session 使用的情况
Session 绑定可以利用负载均衡的源地址 hash 算法实现,负载均衡服务器总是将源于同一 IP 的请求分发到同一台服务器上,即Session 绑定到某台特定服务器上,保证 Session 总能在这台服务器上获取。这种方法又被称作会话黏滞
Session 绑定的方案显然不符合我们对系统高可用的要求,因为一旦某台服务器宕机,那么该机器上的 Session 也就不复存在了,用户请求切换到其他机器后,因为没有 Session 而无法完成业务处理。因此虽然大部分负载均衡服务器都提供源地址负载均衡算法,但很少有网站利用这个算法进行 Session 管理
Cookie 大小受限,能记录的信息有限
每次请求响应都需要传输 Cookie,影响性能
如果用户关闭 Cookie,访问就会不正常了
实际上市将应用服务器的状态分离,分为无状态的应用服务器和有状态的 Session 服务器,然后针对这两种服务器的不同特性分别设计其架构
单点登录和 Session 服务器之间的关系
对于有状态的 Session 服务器,一种比较简单的方式是利用分布式缓存、数据库等,在这些产品的基础上进行包装,使其符合Session 的存储和访问要求。如果业务场景对 Session 管理有比较高的要求,比如利用 Session 服务集成单点登录(SSO)、用户服务等功能,则需要开发专门的 Session 服务管理平台
运维上将服务器进行分级管理,核心应用和服务有限使用更好的硬件,在响应速度上也格外迅速。显然,用户及时付款购物比能不能评价商品更重要,所以订单、支付服务比评价服务有更高优先级
同时在服务部署上也进行必要的隔离,避免故障的连锁反应。低优先级的服务通过启动不同的线程或者部署在不同的虚拟机上进行隔离,而高优先级的服务则需要部署在不同的物理机上,核心服务和数据甚至需要部署在不同地域的数据中心
由于服务器宕机、线程死锁等原因,可能导致应用程序对服务端的调用失去响应,进而导致用户请求长时间得不到响应,同时还占用应用程序的资源,不利于及时将访问请求转移到正常的服务器上
在应用程序中设置服务调用超时时间,一旦超时,通信框架就抛出异常,应用超时后根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上
应用对服务的调用通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况
当然不是所有服务都可以异步调用,对于获取用户信息这类调用,采用异步方式会延长响应时间,得不偿失。对于某些必须确认服务调用成功才能继续下一步操作的应用也不合适使用异步调用
在系统访问高峰期,服务可能因为大量的并发调用而性能下降,严重时可能导致服务宕机。为了保证核心应用和功能的正常执行,需要对服务进行降级。降级有两种手段:拒绝服务和关闭服务
服务重复调用是无法避免的,应用层也不需要关心服务是否真的失败,只要没有收到调用成功的响应,就可以认为调用失败,并重试服务调用。因此必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性
有些服务天然具有幂等性,比如讲用户性别设置为男性,不管设置多少次,结果都是一样。但是对于转账交易等操作,问题就会比较复杂,需要通过交易编号等信息进行服务调用有效性检验,只有有效的操作才能继续执行
保护系统的数据就是保护企业的命脉
保证数据存储高可用的手段主要是数据备份和失效转移机制。数据备份是保证数据有多个副本,任意副本的失效都不会导致数据的永久丢失,从而实现数据完全的持久化。而失效转移机制则保证当一个数据不可访问时,可以快速切换访问数据的其他副本,保证系统可用
缓存服务需要实现和数据存储服务同样的高可用
对于缓存服务器集群中的单机宕机,如果缓存服务器集群规模较大,那么单机宕机引起的缓存数据丢失比例和数据库负载压力变化都较小,对整个系统影响也较小。扩大缓存服务器集群的一个简单手段就是整个系统共享同一个分布式缓存集群,单独的应用和产品不需要部署自己的缓存服务器,只需要向共享缓存集群申请缓存资源即可。并且通过逻辑或物理分区的方式将每个应用的缓存部署在多台服务器上,任何一台服务器宕机引起的缓存失效都只影响应用缓存数据的一部分,不会对应用性能和数据库负载造成太大的影响
C(Consistency:数据一致性,所有应用程序都能访问得到相同的数据
A(Availibility):数据可用性,任何时候、任何应用程序都可以读写访问
P(Patition Tolerance):系统可以跨网络分区线性伸缩CAP 原理对于可伸缩的分布式系统设计具有正要意义,在系统设计开发过程中,不恰当地迎合各种需求,企图打造一个完美的产品,可能回事设计进入两难境地,难以为继
各个副本的数据在物理存储中总是一致的;数据更新操作结果和操作响应总是一致的,即操作响应通知更新失败,那么数据一定没有被更新,而不是处于不确定状态
即数据在物理存储中的各个副本的数据可能是不一致的,但是终端用户访问时,通过纠错和校验机制,可以确定一个一致的且正确的数据返回给用户
这是数据一致性中较弱的一种,即物理存储的数据可能是不一致的,终端用户访问到的数据可能也不是一致的,但系统经过一段时间的自我恢复和修整,数据最终会达到一致
因为难以满足数据一致性,系统通常会综合成本、技术、业务场景等条件,结合应用服务和其他的数据监控与纠错功能,使存储系统达到用户一致,保证最终用户访问数据的正确性
冷备份:优点是简单和廉价,成本和技术难度都交底,缺点是不能保证数据最终一致
数据热备可分为两种:异步热备和同步热备
异步方式指多分数据副本的写入操作异步完成,应用程序收到数据服务系统的写操作成功响应时,只写成功了一份,存储系统会异步地写其他副本
在异步写入方式下,存储服务器分为主存储服务器(Master)和从存储服务器(Slave)、应用程序正常情况下只写入主存储服务器,数据写入时,由主存储服务器的写操作代理模块将数据写入本机存储系统后立即返回写操作成功响应,然后通过异步线程将写操作数据同步到从存储服务器
同步方式是指多份数据副本的写入操作同步完成,即应用程序收到数据服务系统的写成功响应时,多份数据都已经写操作成功。但是当应用程序收到数据写操作失败的响应时,可能有部分副本或者全部副本都已经写成功了
同步热备具体实现的时候,为了提高性能,在应用程序客户端并发向多个存储服务器同时写入数据,然后等待所有存储服务器都返回操作成功的响应后,在通知应用程序写操作成功
这种情况下,存储服务器没有主从之分,完全对等,更便于管理和维护。存储服务客户端在写多分数据的时候,并发操作,这意味着多份数据的总写操作延迟是响应最慢的那台存储服务器的响应延迟,而不是多台存储服务器响应延迟之和。其性能和异步热备方式差不多
关系数据库热备机制通常所说的 Master-Slave 同步机制。Master-Slave 机制不但解决了数据备份问题,还改善了数据库系统的性能,实践中,通常使用读写分离的方法访问 Slave 和 Master 数据库,写操作只访问 Master 数据库,读操作只访问 Slave 数据库
若数据服务集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都需要重新路由到其他服务器,保证数据访问不会失败,这个过程叫做失效转移
有一个控制中心来心跳检测和产生访问失败报告
有对等和不对等的区别,不对等需要重新计算路由,选择存储服务器
MySQL 则可以通过比对主备数据库服务器的二进制日志,通过相关手段来进行恢复
系统的发布过程事实上和服务器宕机效果相当,其对系统可用性的影响也和服务器宕机相似。所以设计一个网站的高可用架构时,需要考虑的服务器宕机概率不是物理上的每年一两次,而是事实上的每周一两次
在高可用的环节中,自动化测试是必不可少的
使用生产环境的数据来测试验证相关功能的正确性,能够提前规避很多的风险
代码修改都在主干(trunk)上进行,需要发布的时候,从主干上来一个分支(branch)发布,该分支即成为一个发布版本,如果该版本发现 Bug,继续在该分支上修改发布,并将修改合并(merge)回主干,直到下次主干发布
任何修改都不得在主干上直接进行,需要开发一个新功能或者修复一个 Bug 时,从主干拉一个分支进行开发,开发完成且测试通过后,合并会主干,然后从主干进行发布,主干上的代码永远是最新发布的版本
主干开发、分支发布方式,主干代码反应目前整个应用的状态,一目了然,便于管理和控制,也利于持续集成
分支开发,主干发布方式,各个分支独立进行,互不干扰,可以使用不同发布周期的开发在同一应用中进行
配合 CI/CD 来完成自动化发布
通过灰度发布来分批上线新功能,并监控反馈
不允许没有监控的系统上线,系统的监控对于系统运维和架构设计优化至关重要
广义上的系统监控涵盖所有非直接业务行为的数据采集与管理,包括供数据分析师和产品设计师使用的系统用户行为日志、业务运行数据、以及供运维工程师和开发工程师使用的系统性能数据
用户行为日志指用户在浏览器上所做的所有操作及其所在的操作系统,包括用户操作系统与浏览器版本信息,IP 地址、页面访问路径、页面停留时间等,这些数据对于统计系统的 PV/UV 指标、分析用户行为、优化系统设计、个性化营销和推荐非常重要
具体的用户行为收集手段有两种:
这个方案比较简单,Apache 等几乎所有 Web 服务器都具备日志记录功能,可以记录大部分用户行为日志,开启 Web 服务器的日志记录功能即可。其缺点是可能会出现信息失真,如 IP 地址是代理服务器地址而不是用户真实 IP;无法识别访问路径等
利用页面嵌入专门的 JavaScript 脚本可以收集真实的操作行为,因此比服务器日志收集更加精准。其缺点是比较麻烦,需要在页面嵌入特定的 JavaScript 脚本来完成
此外,大型系统的用户日志数量惊人,数据存储于计算压力很大,目前许多系统逐步开发基于实时计算框架 Storm、Spark Streaming 的日志统计与分析工具
收集服务器性能指标,如系统 Load、内存占用、磁盘 IO、网络 IO等,尽早做出故障预警,及时判断应用状况,防患于未然,将故障扼杀在萌芽时期非常重要
除了服务器系统性能监控,网站还需要监控一些与具体业务场景相关的技术和业务指标,比如缓存命中率、平均响应时间、每分钟发送邮件数目、待处理的任务总数等
对于服务器性能监控,网站运维人员可以在初始化系统时同一部署,应用程序开发完全不关心服务器性能监控。而运行数据需要在具体程序中采集并报告,汇总后同一显示,应用程序需要在代码中处理运行数据采集逻辑
监控数据采集后,除了用作系统性能评估、集群规模伸缩预测等,还可以根据实时监控数据进行风险预警,并对服务器进行失效转移,自动负载调整,最大化利用集群所有机器的资源
监控管理需要涵盖以下几个方面: