网站的高可用架构
网站的可用性描述网站可有效访问的特性,相比于网站的其他非功能特性,网站的可用性更牵动人们的神经,大型网站的不可用事故直接影响公司形象和利益。
5.2高可用的网站架构
网站高可用架构设计的主要目的是保证服务器硬件故障时服务仍然可用、数据依然保存并能够访问。
实现上述高可用架构的主要手段是数据和服务的冗余备份及失效转移,一旦某些服务器宕机,就将服务切换到其他可用服务器上,如果磁盘损坏,则从备份磁盘读取。
一个典型的网站设计通常遵循下图的基本分层架构模型。
应用层,服务层,数据层各层之间具有相对独立性,应用层主要负责具体业务逻辑处理;服务层提供可复用的服务;数据层负责数据的存储于访问。中小型网站在具体部署时,通常将应用层和服务层部署在一起,数据层另外部署。
在复杂的大型网站架构中划分的粒度会更小,更详细,服务器规模更加庞大。
不同的业务产品会部署在不同的服务器集群上,如文库,贴吧等属于不同的产品,部署在各自独立的服务器集群上,互不相干。这些产品又会依赖一些共同的复用业务,如注册登录服务,Session服务,账户管理服务等,这些可复用的业务也各自部署在独立的服务器集群上。同理,数据层的服务也都部署在各自独立的服务器集群上。
位于应用层和服务层的服务器为了应对高并发的访问请求,会通过负载均衡加集群的方式实现高可用,当有服务不可用时,会立即通知客户端程序修改服务访问列表,剔除不可用的服务器。
位于数据层的服务器情况比较特殊,为了保证服务器宕机时数据不丢失,需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份。
另外,网站升级的频率一般非常高,每次网站发布都需要关闭服务,重新部署系统,整个过程相当于服务器宕机。因此网站的可用性架构设计还要考虑网站升级发布引起的宕机。
5.3高可用的应用
5.3.1通过负载均衡进行无状态服务的失效转移
负载均衡,就是当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上,以提高整体的负载处理能力。在网站应用中,当集群服务时无状态对等时,负载均衡可以起到事实上高可用的作用。
当一台服务器宕机时,负载均衡服务器通过心跳检测机制发现该服务器失去响应,就会将它从服务器列表中删除,而降请求发送到其他服务器上。
5.3.2应用服务器集群的session管理
应用服务器的高可用架构设计主要基于服务无状态这一特性,但是事实上,业务总是有状态的,在交易类的电子商务网站,需要有购物车记录用户的购买信息,在社交类的网站中,需要记录用户的当前登录状态,好用状态等,用户每次刷新页面都需要更新这些信息。
Web应用中将这些多次请求修改使用的上下文对象称为会话(session)。单机情况下,session可以由部署在服务器上的web容器(如JBoss)管理。在使用负载均衡的集群环境中,由于负载均衡服务器可能会将请求分发到集群中任何一台应用服务器上,所以保证每次请求依然能够获得正确的Session比单机时复杂的多。
集群环境下,Session管理主要有以下手段:
1.Session复制
应用服务器开启Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象,使得每台服务器上都保存所有用户的Session信息,这样一台机器的宕机都不会导致session数据的丢失。而服务器使用Session时,也只需在本机获取即可。
但是这种方案在集群规模较大时,集群服务器间需要大量的通信进行Session复制,占用服务器和网络的大量资源,系统不堪重负。而且由于所有用户的Session信息在每台服务器上都有备份,在大量用户访问的情况下,甚至会出现服务器内存不够Session使用的情况。
2.Session绑定
Session绑定可以利用Hash算法实现,负载均衡服务器总是将源于同一IP的请求分发到同一台服务器上(也可以根据Cookie信息将同一个用户的请求总是分发到一台服务器上)这样整个会话期间,用户所有的请求都在同一台服务器上处理,即Session绑定在某台特定服务器上。
但是Session绑定的方案显然不符合对系统高可用的需求,因为一旦某台服务器宕机,那么该机器上的Session也就不赋存在了。虽然大部分负载均衡服务器都提供源地址负载均衡算法,但很少有网站利用这个算法进行Session管理。
3.利用Cookie记录Session
早期的C/S架构,一种管理Session的方式是将Session记录在客户端,每次请求服务器的时候,将Session放在请求中发送给服务器,服务器处理完请求后再将修改过的Session响应给客户端。
网站没有客户端,但是可以利用浏览器支持的Cookie记录Session
利用Cookie记录Session也有一些缺点,比如受Cookie大小限制,能记录的信息有限;每次请求响应都需要传输Cookie,影响性能;如果用户关闭Cookie,访问就会不正常,但是由于Cookie的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分应用需要记录的Session信息又比较小,因此事实上,许多网站都或多或少地使用Cookie记录Session。
4.Session服务器
利用独立部署的Session服务器(集群)统一管理Session,应用服务器每次读写Session时,都访问Session服务器。这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器。
对于有状态的Session服务器,一种比较简单的方法是利用分布式缓存、数据库等,在这些产品的基础上进行包装,使其符合Session的存储和访问要求。如果业务场景对Session管理有比较高的要求,比如利用Session服务继承单点登录,用户服务等功能,则需要开发专门的Session服务器管理平台。
5.4高可用的服务
1.分级管理
运维上将服务器进行分级管理,核心应用和服务优先使用更好的硬件。在服务部署上也进行必要的隔离,避免故障的连锁反应。优先级低的服务通过启动不同的线程或者部署在不同的虚拟机上进行隔离,而优先级高的服务则需要部署在不同的物理机上,核心服务和数据甚至需要部署在不同地域的数据中心。
2.超时设置
由于服务端宕机,线程死锁等问题,可能导致应用程序对服务端调用失去响应。导致用户请求长时间得不到响应,还占用应用程序的资源,不利于及时将访问请求转移到正常的服务器上。
在应用程序中设置服务调用超时时间,一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上。
3.异步调用
应用对服务的调用通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。
4.服务降级
网站访问高峰期,服务可能因为大量并发调用而性能下降,严重时可能导致服务宕机。为了保证核心应用和功能正常运行,需要对服务进行降级。 降级方式有两种:拒绝服务和关闭服务
拒绝服务:拒绝优先级低的应用的调用。减少服务调用并发数,确保核心应用正常使用。或者随机拒绝部分请求,节约资源,让另一部分请求得以成功。
关闭功能:关闭部分不重要的服务,或者服务内部关闭不重要的功能,以节约系统开销,为重要的服务和功能让出资源。淘宝每年的“双十一”促销中就使用这种方法,在系统最繁忙的时段关闭“评价”,确认收货等非核心业务,以保证核心业务服务的顺利完成。
5.5高可用的数据
不同于高可用的应用和服务,由于数据存储服务器上保存的数据不同,当某台服务器宕机时,数据访问请求不能任意切换到集群中其他机器上。
保证数据存储高可用的手段主要是数据备份和失效转移机制。数据备份是保证数据有多个副本,任意副本的失效都不会导致数据的永久丢失,从而实现数据完全的持久化。而失效转移机制则保证当一个数据副本不可访问时,可以快速切换数据的其他副本,保证系统可用。
5.5.1数据备份
数据冷备:冷备的优点是简单和廉价,成本和技术难度都较低。缺点是不能保证数据最终一致,由于数据是定期复制,因此备份设备中的数据比系统中的数据陈旧,如果系统数据丢失,那就会永久丢失一部分数据。同时也没法保证数据可用性,从冷备存储中恢复数据需要较长时间,而这段时间无法访问数据,系统也不可用。
数据冷备作为一种传统数据保护手段,依然在网站日常运维中使用,同时在网站实时在线业务中,还需要进行数据热备,以提供更好的数据可用性。
数据热备:异步热备方式和同步热备方式
异步方式指多份数据副本的写入操作异步完成,应用程序收到数据服务系统的写操作成功响应时,只成功写入了一份,存储系统将会异步地写其他副本。
在异步写入方式下,存储服务器分为主存储服务器和从存储服务器,应用程序正常情况下只连接主存储服务器,数据写入时,由主存储服务器的写操作代理模块写入本机存储系统后立即返回写操作成功响应,然后通过异步线程将写操作数据同步到从存储服务器。
同步方式是指多份数据副本写入操作同步完成,即应用程序收到数据服务系统的写成功响应时,多份数据都已经写操作成功。但是当应用程序收到数据写操作失败的响应时,可能有部分副本或者全部副本都已经写成功了(因为网络或者系统故障,无法返回操作成功的响应)
传统的企业级关系数据库几乎都提供了数据实时备份的机制。而一开始就为大型网站而设计的各种NoSQL数据库更是将数据备份机制作为产品最主要的功能点之一。
关系数据库热备机制就是通常所说的Master-Slave同步机制。Master-Slave机制不但解决了数据备份问题,还改善了数据库系统性能,实践中,通常使用读写分离的方法访问Slave和Master数据库,写操作只访问Master数据库,读操作只访问Slave数据库、
5.5.2失效转移
若一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都需要重新路由到其他服务器,保证数据访问不会失败,这个过程叫作失效转移。
失效转移由三部分组成:失效确认,访问转移,数据恢复
1.失效确认
判断服务器宕机是系统进行失效转移的第一步,系统确认一台服务器是否宕机的手段有两种,心跳检测和程序访问失败报告。
对于应用程序的访问失败报告,控制中心还需要再一次发生心跳检测进行确认,以免错误判断服务器宕机,因为一旦进行数据访问的失效转移,就意味着数据存储多份副本不一致,需要进行后续一系列复杂操作。
2.访问转移
确认某台存储服务器宕机后,就需要将数据读写访问重新路由到其他服务器上。对于完全对等存储的服务器(几台存储服务器存储的数据完全一样,我们成几台服务器为对等服务器,比如主从结构的存储服务器,其存储的数据完全一样),当其中一台宕机后,应用程序根据配置直接切换到对等服务器上。如果存储是不对等的,那么就需要重新计算路由,选择服务器。
3.数据恢复
因为某台服务器宕机,所以数据存储的副本数目会减少,必须将副本的数目恢复到系统设定的值,否则再有服务器宕机时,就可能出现无法访问转移,数据永久丢失的情况。
5.6高可用的软件质量
5.6.1网站发布
不管是发布新功能还是修改了布局等等,都需要在服务器上关闭原因的应用,然后重新部署启动新的应用,整个过程还要求不影响用户的使用。网站发布类似于一次提前预知的服务器宕机,过程可控,对用户影响更小,通常使用发布脚本来完成
发布过程中,每次关闭的服务器都是集群中的一小部分,并在发布完成后立即可以访问。因此整个发布过程不影响用户使用。
5.6.2自动化测试
代码发布到线上之前需要严格的测试。目前大部分网站都采用Web自动化测试技术,使用自动测试工具或脚本完成测试。
比较流行的Web自动测试工具有ThoughtWorks开发的Selenium。selenium运行在浏览器中,自动模拟用户操作进行测试。
大型网站通常也会开发自己的自动化测试工具,可以一键完成系统部署,测试数据生成,测试执行,测试报告生成等全部测试过程。许多测试工程师编码能力毫不逊于软件工程师。
5.6.3预发布验证
即时是经过严格的测试,软件部署到线上还是经常会出现各种问题,甚至根本无法启动服务器。主要原因是测试环境和线上环境并不相同,特别是当应用需要依赖其他服务时,如数据库,缓存,公共业务服务等,以及电信短信网关,银行接口等
因此在网站发布时,并不是把测试通过代码包直接发布到线上服务器,而是先发布到预发布机器上,开发工程师和测试工程师在预发布服务器上进行预发布测试,确认没有问题后再正式发布。
预发布服务器是一种特殊用途的服务器,他和线上服务器唯一区别在于没有配载负载均衡服务器,外部用户没法访问。
预发布服务器和线上正式服务器都部署在相同的物理环境上(同一个数据中心甚至同一个机架,甚至同一个物理服务器上),使用相同的线上配置,依赖相同的外部服务。
不过,也有可能因为预发布验证而引入问题。因为预发布服务器连接的是真实的生产环境,所有的预发布操作都是真实有效的数据,这些操作也许会引起不可预期的问题。比如创建一个店铺,上架一个商品,就有可能有真的用户来购买,如果不能发货,会导致用户投诉。