你的高可用网站具备如下东西了吗
网站可用性度量
网站不可用时间(故障时间) =故障修复时间点一故障发现(报告)时间点
网站年度可用性指标= ( 1 - 网站不可用时间/年度总时间) x 100 %
网站可用性考核
故障分=故障时间(分钟) x 故障权重
高可用的网站架构
高可用架构的主要手段是数据和服务的冗余备份及失效转移, 一旦某些服务器宕机, 就将服务切换到其他可用的服务器上, 如果磁盘损坏, 则从备份的磁盘读取数据。
不同的业务产品会部署在不同的服务器集群上, 如某网站的文库、贴吧、百科等属于不同的产品, 部署在各自独立的服务器集群上, 互不相干。这些产品又会依赖一些共同的复用业务, 如注册登录服务、Session 管理服务、账户管理服务等, 这些可复用的业务服务也各自部署在独立的服务器集群上。至于数据层,数据库服务、文件服务、缓存服务、搜索服务等数据存储与访问服务都部署在各自独立的服务器集群上。
大型网站的分层架构及物理服务器的分布式部署使得位于不同层次的服务器具有不同的可用性特点。关闭服务或者服务器宕机时产生的影响也不相同,高可用的解决方案也差异甚大。
应用层
位于应用层的服务器通常为了应对高并发的访问请求,会通过负载均衡设备将一组服务器组成一个集群共同对外提供服务,当负载均衡设备通过心跳检测等手段监控到某台应用服务器不可用时,就将其从集群列表中剔除, 并将请求分发到集群中其他可用的
服务器上,使整个集群保持可用,从而实现应用高可用。
服务层
位于服务层的服务器情况和应用层的服务器类似,也是通过集群方式实现高可用,只是这些服务器被应用层通过分布式服务调用框架访问,分布式服务调用框架会在应用层客户端程序中实现软件负载均衡, 并通过服务注册中心对提供服务的服务器进行心跳检测,发现有服务不可用,立即通知客户端程序修改服务访问列表,剔除不可用的服务器。
数据层
位于数据层的服务器情况比较特殊, 数据服务器上存储着数据, 为了保证服务器宕机时数据不丢失,数据访问服务不中断, 需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份。当数据服务器宕机时, 应用程序将访问切换到有备份数据的服务器上。
高可用的应用
应用层主要处理网站应用的业务逻辑,因此有时也称作业务逻辑层, 应用的一个显著特点是应用的无状态性。所谓无状态的应用是指应用服务器不保存业务的上下文信息, 而仅根据每次请求提交的数据进行相应的业务逻辑处理, 多个服务实例(服务器)之间完全对等, 请求提交到任意服务器, 处理结果都是完全一样的。
通过负载均衡进行无状态服务的失效转移
通过负载均衡手段, 将流量和数据分摊到一个集群组成的多台服务器上,以提高整体的负载处理能力。
当Web 服务器集群中的服务器都可用时,负载均衡服务器会把用户发送的访问请求分发到任意一台服务器上进行处理, 而当服务器宕机时, 负载均衡服务器通过心跳检测机制发现该服务器失去响应, 就会把它从服务器列表中删除,而将请求发送到其他服务器上,这些服务器是完全一样的, 请求在任何一台服务器中处理都不会影响最终的结果。
应用服务器集群的Session 管理
1. Session 复制
应用服务器开启Web 容器的Session 复制功能, 在集群中的几台服务器之间同步Session 对象,使得每台服务器上都保存所有用户的Session 信息, 这样任何一台机器宕机都不会导致Session 数据的丢失, 而服务器使用Session 时, 也只需要在本机获取即可。
当集群规模较大时, 集群服务器问需要大量的通信进行SessioD 复制, 占用服务器和网络的大量资源, 系统不堪负担。
2. Session 绑定
Session 绑定可以利用负载均衡的源地址Hash 算法实现。负载均衡服务器总是将来源于同- lP 的请求分发到同一台服务器上。
但是Session 绑定的方案显然不符合我们对系统高可用的需求, 因为一旦某台服务器宕机,那么该机器上的SessioD 也就不复存在了,用户请求切换到其他机器后因为没有SessioD 而无法完成业务处理。因此虽然大部分负载均衡服务器都提供源地址负载均衡算法, 但很少有网站利用这个算法进行Session 管理。
3. 利用Cookie 记录Session
早期的企业应用系统使用C/S (客户端/服务器)架构,一种管理Session 的方式是将Session 记录在客户端, 每次请求服务器的时候, 将Session 放在请求中发送给服务器, 服务器处理完请求后再将修改过的SessioD 响应给客户端。网站没有客户端,但是可以利用浏览器支持的Cookie 记录Session 。利用Cookie 记录Session 也有一些缺点, 比如受Cookie 大小限制, 能记录的信息有限; 每次请求响应都需要传输Cookie, 影响性能; 如果用户关闭Cookie , 访问就会不正常。但是由于Cookie 的简单易用,可用性高, 支持应用服务器的线性伸缩, 而大部分应用需要记录的Sessio信息又比较小。因此事实上, 许多网站都或多或少地使用Cookie记录Session。
4. Session 服务器
利用独立部署的Session 服务器(集群) 统一管理Session ,应用服务器每次读写Session 时, 都访问Session 服务器。
将应用服务器的状态分离, 分为无状态的应用服务器和有状态的Session 服务器, 然后针对这两种服务器的不同特性分别设计其架构。
对于有状态的Session 服务器, 一种比较简单的方法是利用分布式缓存、数据库等,在这些产品的基础上进行包装, 使其符合Session 的存储和访问要求。如果业务场景对Session 管理有比较高的要求, 比如利用Session 服务集成单点登录( SSO ) 、用户服务等功能, 则需要开发专门的Session 服务管理平台。
高可用的服务
1 .分级管理
运维上将服务器进行分级管理,核心应用和服务优先使用更好的硬件在运维响应速度上也格外迅速。显然, 用户及时付款购物比能不能评价商品更重要, 所以订单、支付服务比评价服务有更高优先级。同时在服务部署上也进行必要的隔离,避免故障的连锁反应。低优先级的服务通过启动不同的线程或者部署在不同的虚拟机上进行隔离,而高优先级的服务则需要部署在不同的物理机上,核心服务和数据甚至需要部署在不同地域的数据中心。
2. 超时设置
由于服务端宕机、线程死锁等原因,可能导致应用程序对服务端的调用失去响应,进而导致用户请求长时间得不到响应,同时还占用应用程序的资源,不利于及时将访问请求转移到正常的服务器上。在应用程序中设置服务调用的超时时间, 一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上。
3. 异步调用
应用对服务的调用通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。
当然不是所有服务调用都可以异步调用,对于获取用户信息这类调用, 采用异步方式会延长响应时间, 得不偿失。对于那些必须确认服务调用成功才能继续下一步操作的应用也不合适使用异步调用。
4 . 服务降级
拒绝服务: 拒绝低优先级应用的调用, 减少服务调用并发数, 确保核心应用正常使用; 或者随机拒绝部分请求调用, 节约资源, 让另一部分请求得以成功, 避免要死大家一起死的惨剧。
关闭功能: 关闭部分不重要的服务, 或者服务内部关闭部分不重要的功能, 以节约系统开销, 为重要的服务和功能让出资源。
5. 幂等性设计
应用调用服务失败后, 会将调用请求重新发送到其他服务器, 但是这个失败可能是虚假的失败。比如服务已经处理成功, 但因为网络故障应用没有收到响应, 这时应用重新提交请求就导致服务重复调用, 如果这个服务是一个转账操作, 就会产生严重后果。服务重复调用是无法避免的, 应用层也不需要关心服务是否真的失败, 只要没有收到调用成功的响应就可以认为词用失败, 并重试服务调用。因此必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。
高可用的数据
扩大缓存服务器集群规模的一个简单手段就是整个网站共享同一个分布式缓存集群, 单独的应用和产品不需要部署自己的缓存服务器, 只需要向共享缓存集群申请缓存资源即可。并且通过逻辑或物理分区的方式将每个应用的缓存部署在多台服务器上,任何一台服务器岩机引起的缓存失效都只影响应用缓存数据的一小部分,不会对应用性能和数据库负载造成太大影响。
CAP 原理
数据持久性:
为了实现数据的持久性, 不但在写入数据时需要写入持久性存储, 还需要将数据备份一个或多个副本存放在不同的物理存储设备上,在某个存储故障或灾害发生时,数据不会丢失。
数据可访问性:
在多份数据副本分别存放在不同存储设备的情况下, 如果一个数据存储设备损坏,就需要将数据访问切换到另一个数据存储设备上, 如果这个过程不能很快完成(终端用户几乎没有感知) ,或者在完成过程中需要停止终端用户访问数据,那么这段时间数据是不可访问的。
数据一致性:
在数据有多份副本的情况下, 如果网络、服务器或者软件出现故障, 会导致部分副本写入成功, 部分副本写入失败。这就会造成各个副本之间的数据不一致, 数据内容冲突。实践中, 导致数据不一致的情形有很多种,表现形式也多种多样, 比如数据更新返回操作失败,事实上数据'在存储服务器已经更新成功。
数据一致性又可分为如下几点:
数据强一致
各个副本的数据在物理存储中总是一致的; 数据更新操作结果和操作响应总是一致的, 即操作响应通知更新失败, 那么数据一定没有被更新, 而不是处于不确定状态。
数据用户一致
即数据在物理存储中的各个副本的数据可能是不一致的, 但是终端用户访问时, 通过纠错和校验机制, 可以确定一个一致的且正确的数据返回给用户。
数据最终一致
这是数据一致性中较弱的一种, 即物理存储的数据可能是不一致的, 终端用户访问到的数据可能也是不一致的(同一用户连续访问, 结果不同; 或者不同用户同时访问,结果不同) ,但系统经过一段时间(通常是一个比较短的时间段)的自我恢复和修正,数据最终会达到一致。
数据备份
数据冷备:
即定期将数据复制到某种存储介质(磁带, 光盘……) 上并物理存档保管, 如果系统存储损坏, 那么就从冷备的存储设备中恢复数据。
冷备的优点:简单和廉价, 成本和技术难度都较低。
缺点:是不能保证数据最终一致,由于数据是定期复制, 因此备份设备中的数据比系统中的数据陈旧, 如果系统数据丢失,那么从上个备份点开始后更新的数据就会永久丢失, 不能从备份中恢复。同时也不能保证数据可用性, 从冷备存储中恢复数据需要较长的时间, 而这段时间无法访问数据, 系统也不可用。
数据热备:
数据热备可分为两种: 异步热备方式和同步热备方式。
异步方式是指多份数据副本的写入操作异步完成, 应用程序收到数据服务系统的写操作成功响应时, 只写成功了一份,存储系统将会异步地写其他副本(这个过程有可能会失败)。
在异步写入方式下, 存储服务器分为主存储服务器( Master )和从存储服务器( Slave ),应用程序正常情况下只连接主存储服务器, 数据写入时, 由主存储服务器的写操作代理模块将数据写入本机存储系统后立即返回写操作成功响应, 然后通过异步线程将写操作数据同步到从存储服务器。
同步方式是指多份数据副本的写入操作同步完成,即应用程序收到数据服务系统的写成功响应时, 多份数据都已经写操作成功。但是当应用程序收到数据写操作失败的响应时, 可能有部分副本或者全部副本都已经写成功了(因为网络或者系统故障,无法返回操作成功的响应)
同步热备具体实现的时候,为了提高性能,在应用程序客户端并发向多个存储服务器同时写入数据, 然后等待所有存储服务器都返回操作成功的响应后, 再通知应用程序写操作成功。
这种情况下,存储服务器没有主从之分,完全对等, 更便于管理和维护。存储服务客户端在写多份数据的时候,并发操作, 这意味着多份数据的总写操作延迟是响应最慢的那台存储服务器的响应延迟,而不是多台存储服务器响应延迟之和。其性能和异步热备方式差不多。
失效转移
若数据服务器集群中任何一台服务楼宕机,那么应用程序针对这台服务器的所有读写操作都需要重新路由到其他服务器, 保证数据访问不会失败, 这个过程叫作失效转移。失效转移操作由三部分组成: 失效确认、访问转移、数据恢复。
1.失效确认:
判断服务器宕机是系统进行失效转移的第一步, 系统确认一台服务器是否右机的手段有两种: 心跳检测和应用程序访问失败报告
对于应用程序的访问失败报告, 控制中心还需要再一次发送心跳检测进行确认,以免错误判断服务器窑机, 因为一旦进行数据访问的失效转移, 就意味着数据存储多份副本不一致, 需要进行后续一系列复杂的操作。
2.访问转移
确认某台数据存储服务器宕机后, 就需要将数据读写访问重新路由到其他服务器上。对于完全对等存储的服务器(几台存储服务器存储的数据完全一样, 我们称几台服务器为对等服务器,比如主从结构的存储服务器,其存储的数据完全一样),当其中一台宕机后, 应用程序根据配置直接切换到对等服务器上。如果存储是不对等的, 那么就需要重新计算路由, 选择存储服务器。
3 . 数据恢复
因为某台服务器宕机, 所以数据存储的副本数目会减少, 必须将副本的数目恢复到系统设定的值,否则, 再有服务器言机时, 就可能出现无法访问转移(所有副本的服务器宕机了), 数据永久丢失的情况。因此系统需要从健康的服务器复制数据, 将数据副本数目恢复到设定值。
高可用网站的软件质量保证
1.网站发布
不管发布的新功能是修改了一个按钮的布局还是增加了一个核心业务, 都需要在服务器上关闭原有的应用, 然后重新部署启动新的应用, 整个过程还要求不影响用户的使用。
网站应用发布流程:
发布过程中, 每次关闭的服务器都是集群中的一小部分,并在发布完成后立即可以访问,因此整个发布过程不影响用户使用。
2.自动化测试
为了保证系统没有引入未预料的Bug , 网站测试还是需要对整个网站功能进行全面的回归测试。此外还需要测试各种浏览器的兼容性。在发布频繁的网站应用中,如果使用人工测试,成本、时间及测试覆盖率都难以接受。目前大部分网站都采用Web 自动化测试技术,使用自动测试工具或脚本完成测试。
3.预发布验证
在网站发布时, 并不是把测试通过的代码包直接发布到线上服务器, 而是先发布到预发布机器上, 开发工程师和测试工程师在预发布服务器上进行预发布验证,执行一些典型的业务流程,确认系统没有问题后才正式发布。预发布服务器是一种特殊用途的服务器, 它和线上的正式服务器唯一的不同就是没有配置在负载均衡服务器上,外部用户无法访问。
预发布服务器和线上正式服务器(应用服务器1 , 2 , 3) 都部署在相同的物理环境(同一个数据中心甚至同一个机架上, 如果使用虚拟机, 甚至可能在同一个物理服务器上)中, 使用相同的线上配置, 依赖相同的外部服务。网站工程师通过在自己的开发用计算机上配置hosts 文件绑定域名IP 关系直接使用IP 地址访问预发布服务器。如果在预发布服务器上执行的测试验证是正确的, 基本可以确保在线上正式服务器部署时也没有问题。不过,也有可能会因为预发布验证而引入问题。因为预发布服务器连接的是真实的生产环境, 所有的预发布验证操作都是真实有效的数据,这些操作也许会引起不可预期的问题。比如创建一个店铺, 上架一个商品, 就有可能有真的用户过来购买, 如果不能发货, 会导致用户投诉。此外, 在网站应用中强调的一个处理错误的理念是快速失败( fast failed ),即如果系统在启动时发现问题就立刻抛出异常, 停止启动让工程师介入排查错误, 而不是启动后执行错误的操作。
4.代码控制
1 . 主干开发、分支发布
代码修改都在主干( trunk ) 上进行, 需要发布的时候, 从主干上拉一个分支( branch )发布, 该分支即成为一个发布版本, 如果该版本发现Bug , 继续在该分支上修改发布, 并将修改合并( merge ) 回主干,直到下次主干发布。
2. 分支开发,主干发布
任何修改都不得在主干上直接进行, 需要开发一个新功能或者修复一个Bug 时,从主干拉一个分支进行开发,开发完成且测试通过后,合并回主干,然后从主干进行发布,主干上的代码永远是最新发布的版本。
这两种方式各有优缺点。主干开发、分支发布方式,主干代码反应目前整个应用的状态,一目了然, 便于管理和控制,也利于持续集成。分支开发, 主干发布方式,各个分支独立进行,互不干扰,可以使不同发布周期的开发在同一应用中进行。
5.自动化发布
很多网站选择周四作为发布日, 这样一周前面有三天时间可以准备发布, 后面还有一天时间可以挽回错误。如果选择周五发布, 发现问题就必须要周末加班了。
由于火车发布模型是基于规则驱动的流程, 所以这个流程可以自动化。采用火车发布模型的网站会开发一个自动化发布的工具实现发布过程的自动化。根据响应驱动流程,自动构造代码分支, 进行代码合并, 执行发布脚本等。正常流程下, 可以做到发布过程无人值守,无需SCM (网站配置管理员)参与,每个项目相关人员基于流程执行相应的操作,即可完成应用自动发布。人的干预、越少,自动化程度越高,引入故障的可能性就越小,火车准点到达,大家按时下班的可能性就越大。
6.灰度发布
应用发布成功后,仍然可能发现因为软件问题而引入的故障, 这时候就需要做发布回滚,即卸载刚刚发布的软件,将上一个版本的软件包重新发布,使系统复原, 消除故障。
大型网站的主要业务服务器集群规模非常庞大,比如某大型应用集群服务器数量超过一万台。一旦发现故障,即使想要发布回滚也需要很长时间才能完成,只能眼睁睁看着故障时间不断增加却干着急。为了应付这种局面, 大型网站会使用灰度发布模式,将集群服务器分成若干部分, 每天只发布一部分服务器, 观察运行稳定没有故障,第二天继续发布一部分服务器,持续几天才把整个集群全部发布完毕,期间如果发现问题, 只需要回滚已发布的一部分服务器即可。
灰度发布也常用于用户测试,即在部分服务器上发布新版本,其余服务器保持老版本(或者发布另一个版本),然后监控用户操作行为,收集用户体验报告,比较用户对两个版本的满意度,以确定最终的发布版本。这种手段也被称作AB 测试。
网站运行监控(不允许没有监控的系统上线)
1.监控数据采集
1 .用户行为日志收集
用户行为日志指用户在浏览器上所做的所有操作及其所在的操作环境, 包括用户操作系统与浏览器版本信息, IP 地址、页面访问路径、页面停留时间等, 这些数据对统计网站PV/UV 指标、分析用户行为飞优化网站设计、个性化营销与推荐等非常重要。
具体用户行为日志收集手段有两种。
服务器端日志收集。这个方案比较简单, Apache 等几乎所有Web 服务器都具备日忘记录功能, 可以记录大部分用户行为日志, 开启Web 服务器的日志记录功能即可。其缺点是可能会出现信息失真, 如IP 地址是代理服务器地址而不是用户真实IP; 无法识别访问路径等。
客户端浏览器日志收集。利用页面嵌入专门的JavaScript 脚本可以收集用户真实的操作行为, 因此比服务器日志收集更加精准。其缺点是比较麻烦, 需要在页面嵌入特定的JavaScript 脚本来完成。
此外, 大型网站的用户日志数据量惊人, 数据存储与计算压力很大, 目前许多网站逐步开发基于实时计算框架Storm 的日志统计与分析工具。
2. 服务器性能监控
收集服务器性能指标, 如系统Load 、内存占用飞磁盘IO 、网络IO 等对尽早做出故障预警, 及时判断应用状况, 防患于未然, 将故障扼杀在萌芽时期非常重要。此外根据性能监控数据, 运维工程师可以合理安排服务器集群规模, 架构师及时改善系统性能及调整系统伸缩性策略。目前网站使用比较广泛的开源性能监控工具是Ganglia , 它支持大规模服务器集群,并支持以图形的方式在浏览器展示实时性能曲线。
3 . 运行数据报告
除了服务器系统性能监控,网站还需要监控一些与具体业务场景相关的技术和业务指标, 比如缓冲命中率、平均响应延迟时间、每分钟发送邮件数目、待处理的任务总数等。
对于服务器性能监控,网站运维人员可以在初始化系统时统一部署,应用程序开发完全不关心服务器性能监控。而运行数据需要在具体程序中采集并报告, 汇总后统一显示,应用程序需要在代码中处理运行数据采集的逻辑。
监控管理
监控数据采集后,除了用作系统性能评估、集群规模伸缩性预测等,还可以根据实时监控数据进行风险预警, 并对服务器进行失效转移, 自动负载调整,最大化利用集群所有机器的资源。
系统报警
在服务器运行正常的情况下, 其各项监控指标基本稳定在一个特定水平,如果这些指标超过某个阐值, 就意味着系统可能将要出现故障,这时就需要对相关人员报警, 及时采取措施,在故障还未真正发生时就将其扼杀在萌芽状态。监控管理系统可以配置报警阔值和值守人员的联系方式,报警方式除了邮件, 即时通信工具, 还可以配置手机短信,语音报警,系统发生报警时,工程师即使在千里之外、夜里睡觉也能被及时通知, 迅速响应。
失效转移
除了应用程序访问失败时进行失效转移,监控系统还可以在发现故障的情况下主动通知应用,进行失效转移。
自动优雅降级
优雅降级是指网站为了应付突然爆发的访问高峰, 主动关闭部分功能, 释放部分系统资源,保证网站核心功能正常访问的一个手段。网站在监控管理基础之上实现自动优雅降级, 是网站柔性架构的理想状态:监控系统实时监控所有服务器的运行状况,根据监控参数判断应用访问负载情况,如果发现部分应用负载过高,而部分应用负载过低,就会适当卸载低负载应用部分服务器, 重新安装启动部分高负载应用, 使应用负载总体均衡,如果所有应用负载都很高, 而且负载压力还在继续增加,就会自动关闭部分非重要功能,保证核心功能正常运行。