前言:
系统的高可用架构就是要在上述各种故障情况下,保证系统依然可用提供服务,具体包括以下几种架构方案。
各种服务器故障是不可避免的,架构设计上就要保证,当服务器故障的时候,系统依然可用访问。
冗余备份是提供同一服务的服务器要进行冗余备份的处理,即任何服务都不能只有一台服务器,服务器之间要互相进行备份处理,任何一台服务器出现故障的时候,请求可用发送到备份的服务器去处理,这样,即使某台服务器失效,系统依然是可用的。
在负载均衡架构中,可用将多台应用服务器构成一个集群一起对外提供服务,这样可以利用多台应用服务器的计算资源,满足高并发的用户访问请求,事实上,负载均衡可以实现系统的高可用。
负载均衡服务器通过心跳检测发现集群中某台应用服务器失效,然后负载均衡服务器就不将请求分发给这台服务器,对用户而言,也就感觉不到存在服务器失效的情况,系统依然是可用的。
像阿里巴巴这样的大厂就是通过这种方式来实现的,应用程序升级的时候,停止应用进程,但是不影响用户的访问,因为应用程序部署在多台服务器上面,应用程序升级的时候,每次只停止一台或者一部分服务器即可,在这些机器上进行程序升级,这个时候,集群中海油其他服务器在提供服务器,因此用户感觉不到服务器已经停机了。
保证系统高可用的另外一个策略是失败隔离,将失败隔离在一个较小的范围之内,使故障影响范围不扩大,失败隔离的主要架构技术是消息队列。
消息的生产者和消费者通过消息队列进行隔离,如果消费者出现故障的时候,生产者可以继续向消息队列发送消息,而不会感知到消费者的故障,等消费者恢复正常以后再去从消息队列中消费消息,所以用户处理的视角来看,系统一直是正常使用的。
例如:发送邮件或者短线的消费者出现了故障,不会影响到生产者应用的运行,也不会影响发送短线等其他消费者的正常的运行。
另一方面,由于分布式消息队列具有削峰填谷的作用,所以在高并发的时候,消息的生产者可以将消息缓冲在分布式消息队列中,消费者可以慢慢地从消息队列中处理,而不会将瞬时的高并发负载压力直接对整个系统进行施压的冲击。导致系统的崩溃,也就是将压力给降下来,使消息生产者的访问压力不会直接传递到消息的消费者上面,这样可以提高数据库的可用性。
消息队列还使得程序解耦,将程序的调用和依赖隔离开来,低耦合的程序更加易于维护,可以减少程序出现的bug的可能性。
限流和降级是保护系统高可用的一种手段,在高并发场景下,系统的访问量超过了系统的承受能力的话,可以通过限流对系统进行保护,限流是指对进入系统的用户请求进行流量的限制处理,如果访问量超过了系统的最大处理能力的话,就会丢失一部分的用户请求,保证整个系统可以正常使用,保证了大部分用户的访问系统是正常的,这样虽然有一部分用户的请求被丢弃,产生了部分的不可用,但是对于整个系统都崩溃来说,比较友好。
降级是保护系统的另一种手段,有一些系统功能是非核心的,但是他也给系统产生了非常大的压力,比如说电商系统中确认收货这个功能,即使我们不去确认收货,系统也会超时自动确认收货的处理。
但是实际上确认收货这个操作是一个非常中的操作,因为它会对数据库产生很大的压力,他要进行更改订单的状态,完成支付的确认,进行评价等一系列的操作,如果在系统中高并发的时候去完成这些操作,那么会对系统进行雪上加霜,使得系统的处理能力更加的恶化。
解决的办法是在系统高并发的时候,比如说淘宝双11的时候,当天可能整天系统都处于一种极限的高并发访问压力之下,这个时候就可以把确认收货、评价这些非功能进行关闭处理,将宝贵的系统资源保留下来,让给正在购物的人进行下单交易的处理。
异地多活的原理,采用了异地多活的多机房的机制,数据中心分布叜多个不同地点的机房里面,这些机房都可以对外提供服务,用户可以连接任何一个机房进行访问处理,这样每个机房都可以提供完整的系统服务,即使某一个机房不可使用,系统也不会产生宕机的可能,保证了系统的可用性。
异地多活架构考虑的重点就是,用户请求如何分发到不同的机房上面。这个主要可用在域名解析的时候完成操作,也就是用户进行域名解析的时候,会根据就近原则或者其他的一些策略,完成用户请求的分发,另一个至关重要的技术点是,因为是多个机房都可以独立对外提供服务,所以也就意味着每个机房都要有完整的数据记录,用户在任何一个机房完成的数据操作,都必须同步传输给其他机房,进行数据实时的同步处理。
数据库实时同步最重要的关注点是数据冲突的问题,同一条数据,同时在两个数据中心被修改了,该如何进行解决处理,为了解决这种数据冲突的问题,某些容易引起数据冲突的服务采用类似MySql的主主模式进行处理,也就是说多个机房在某个时刻有一个主机房的,某些请求只能到达主机房才能被处理,其他的机房不处理这一类的请求,使用该方法进行避免产生数据的冲突。