十年前的阿里大牛困惑:咱们为何感受不到淘宝应用升级时的停机?

十年前的阿里大牛困惑:咱们为何感受不到淘宝应用升级时的停机?

本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等git

十几年前,我参加阿里巴巴面试的时候,以为阿里巴巴这样的网站 Web 应用开发简直小菜,由于我以前是作相似 Tomcat 这样的 Web 容器开发的,因此面试的时候信心满满。github

确实,面试官前面的问题都是关于数据结构、操做系统、设计模式的,也就是咱们这个专栏模块一和模块二的内容。我感受本身回答得还不错,因此更加信心满满。这时候,面试官突然提了一个问题:面试

咱们的 Web 程序每一个星期都会发布一个新版本,可是程序要求 7*24 小时可用,也就是说,启动新版本程序替换老程序,进行程序升级的时候,程序还在对外提供服务,用户没有感受到停机,咱们是怎么作到的呢?数据库

应用程序升级必需要用新版本的程序包替代老版本的程序包,并从新启动程序,这段时间程序是不能对外提供服务的,用户请求必定会失败。可是阿里巴巴让这段时间的用户请求依然是成功的。打个比方,就是要在飞机飞行过程当中更换发动机,还不能让乘客感受到。这个问题当时彻底不在个人知识范围以内,可是我知道这个需求场景是真实存在的,并且确实应该是能够作到的,但是我彻底不知道是怎么作到的。设计模式

面试官看我瞠目结舌,笑着问我,想不想知道答案。我马上回答说想知道,结果面试官跟我说,加入咱们团队你就知道了。服务器

这实际上是一个关于互联网应用可用性的问题。咱们知道,Web 应用在各类状况下都有可能不可访问,也就是不可用。各类硬件故障,好比应用服务器及数据库宕机、网络交换机宕机、磁盘损坏、网卡松掉等等。还有各类软件故障,程序 Bug 什么的。即便没有 Bug,程序要升级,必需要关闭进程从新启动,这段时间应用也是不可用的;此外,还有外部环境引起的不可用,好比促销引来大量用户访问,致使系统并发压力太大而崩溃,以及,******、机房火灾、挖掘机挖断光缆,各类状况致使的应用不可用。微信

而互联网的高可用是说,在上面各类状况下,应用都要是可用的,用户都可以正常访问系统,完成业务处理。网络

这彷佛是不可能的任务。数据结构

高可用的度量

首先咱们看下,什么叫作应用的高可用,以及可用性如何度量。业界一般用多少个 9 来讲明互联网应用的可用性。好比说淘宝的可用性是 4 个 9,就是说淘宝的服务 99.99% 可用。这句话的意思是,淘宝的服务要保证在全部的运行时间里只有 0.01% 不可用,也就是说一年大概有 53 分钟不可用。这个 99.99% 就叫作系统的可用性指标,这个值的计算公式是:架构

十年前的阿里大牛困惑:咱们为何感受不到淘宝应用升级时的停机?

通常说来,两个 9 表示系统基本可用,年度不可用时间小于 88 小时;3 个 9 是较高可用,年度不可用时间小于 9 个小时;4 个 9 是具备自动恢复能力的高可用,年度不可用时间小于 53 分钟;5 个 9 指极高的可用性,年度不可用时间小于 5 分钟。咱们熟悉的互联网产品的可用性大可能是 4 个 9。淘宝、百度、微信,差很少都是这样。

下面我会讨论各类高可用技术方案。但无论是哪一种方案,实现高可用须要投入的技术和设备成本都很是高。所以可用性并非越高越好,而是要根据产品策略寻找高可用投入产出的最佳平衡点,像支付宝这样的金融产品就须要更高的可用性,而微博的可用性要求就会相对低一些。相对支付宝的可用性超过 99.99%,Twitter 的可用性只有 98%。

可用性指标是对系统总体可用性的一个度量。在互联网企业中,为了更好地管理系统的可用性,界定好系统故障之后的责任,一般会用故障分进行管理。通常过程是,根据系统可用性指标换算成一个故障分,这个故障分是整个系统的故障分,好比 10 万分,而后根据各自团队各个产品各个职能角色承担的责任的不一样,把故障分下发给每一个团队,直到每一个人,也就是说每一个工程师在年初的时候就会收到一个预计的故障分。而后每一次系统出现可用性故障间小于 53 分钟;5 个 9 指极高的可用性,年度不可用时间小于 5 分钟。咱们熟悉的互联网产品的可用性大可能是 4 个 9。淘宝、百度、微信,差很少都是这样。

下面我会讨论各类高可用技术方案。但无论是哪一种方案,实现高可用须要投入的技术和设备成本都很是高。所以可用性并非越高越好,而是要根据产品策略寻找高可用投入产出的最佳平衡点,像支付宝这样的金融产品就须要更高的可用性,而微博的可用性要求就会相对低一些。相对支付宝的可用性超过 99.99%,Twitter 的可用性只有 98%。

可用性指标是对系统总体可用性的一个度量。在互联网企业中,为了更好地管理系统的可用性,界定好系统故障之后的责任,一般会用故障分进行管理。通常过程是,根据系统可用性指标换算成一个故障分,这个故障分是整个系统的故障分,好比 10 万分,而后根据各自团队各个产品各个职能角色承担的责任的不一样,把故障分下发给每一个团队,直到每一个人,也就是说每一个工程师在年初的时候就会收到一个预计的故障分。而后每一次系统出现可用性故障的时候,都会进行故障考核,划定到具体的团队和责任人之后,会扣除他的故障分。若是到了年末的时候,若是一个工程师的故障分为负分,那么颇有可能会影响他的绩效考核。

故障分=故障时间*故障权重

高可用的架构

系统的高可用架构就是要在上述各类故障状况下,保证系统依然能够提供服务,具体包含如下几种架构方案。咱们已经在前面几篇架构专栏中提到过这些架构方案,这里咱们从高可用
的视角从新审视如下这些架构是如何实现高可用的。

冗余备份

既然各类服务器故障是不可避免的,那么架构设计上就要保证,当服务器故障的时候,系统依然能够访问。具体上就是要实现服务器的冗余备份。

冗余备份是说,提供同一服务的服务器要存在冗余,即任何服务都不能只有一台服务器,服务器之间要互相进行备份,任何一台服务器出现故障的时候,请求能够发送到备份的服务器去处理。这样,即便某台服务器失效,在用户看来,系统依然是可用的。

我在负载均衡架构这篇文章中讲了经过负载均衡服务器,将多台应用服务器构成一个集群共同对外提供服务,这样能够利用多台应用服务器的计算资源,知足高并发的用户访问请求。事实上,负载均衡还能够实现系统的高可用

十年前的阿里大牛困惑:咱们为何感受不到淘宝应用升级时的停机?

负载均衡服务器经过心跳检测发现集群中某台应用服务器失效,而后负载均衡服务器就不将请求分发给这台服务器,对用户而言,也就感受不到有服务器失效,系统依然可用。

回到咱们开头的问题,阿里巴巴就是用这种方法实现的。应用程序升级的时候,中止应用进程,可是不影响用户访问。由于应用程序部署在多台服务器上,应用程序升级的时候,每次只 STOP 一台或者一部分服务器,在这些机器上进行程序升级,这个时候,集群中还有其余服务器在提供服务器,所以用户感受不到服务器已经停机了。

此外我在数据存储架构这篇文章中提到的数据库主主复制,也是一种冗余备份。这个时候,不仅是数据库系统 RDBMS 互相进行冗余备份,数据库里的数据也要进行冗余备份,一份数据存储在多台服务器里,保证当任何一台服务器失效,数据库服务依然可使用。

失败隔离

保证系统高可用的另外一个策略是失败隔离,将失败限制在一个较小的范围以内,使故障影响范围不扩大。具体实现失败隔离的主要架构技术是消息队列。

一方面,消息的生产者和消费者经过消息队列进行隔离。若是消费者出现故障的时候,生产者能够继续向消息队列发送消息,而不会感知到消费者的故障,等消费者恢复正常之后再去从消息队列中消费消息,因此从用户处理的视角看,系统一直是可用的。

发送邮件消费者出现故障,不会影响生产者应用的运行,也不会影响发送短信等其余消费者正常的运行。

十年前的阿里大牛困惑:咱们为何感受不到淘宝应用升级时的停机?

另外一方面,因为分布式消息队列具备削峰填谷的做用,因此在高并发的时候,消息的生产者能够将消息缓冲在分布式消息队列中,消费者能够慢慢地从消息队列中去处理,而不会将瞬时的高并发负载压力直接施加到整个系统上,致使系统崩溃。也就是将压力隔离开来,使消息生产者的访问压力不会直接传递到消息的消费者,这样能够提升数据库等对压力比较敏感的服务的可用性。

同时,消息队列还使得程序解耦,将程序的调用和依赖隔离开来,咱们知道,低耦合的程序更加易于维护,也能够减小程序出现 Bug 的概率。

限流降级

限流和降级也是保护系统高可用的一种手段。在高并发场景下,若是系统的访问量超过了系统的承受能力,能够经过限流对系统进行保护。限流是指对进入系统的用户请求进行流量限制,若是访问量超过了系统的最大处理能力,就会丢弃一部分的用户请求,保证整个系统可用,保证大部分用户是能够访问系统的。这样虽然有一部分用户的请求被丢弃,产生了部分不可用,但仍是好过整个系统崩溃,全部的用户都不可用要好。

降级是保护系统的另外一种手段。有一些系统功能是非核心的,可是它也给系统产生了很是大的压力,好比说在电商系统中有确认收货这个功能,即使咱们不去确认收货,系统也会超时自动确认收货。

但实际上确认收货这个操做是一个很是重的操做,由于它会对数据库产生很大的压力:它要进行更改订单状态,完成支付确认,并进行评价等一系列操做。若是在系统高并发的时候去完成这些操做,那么会对系统雪上加霜,使系统的处理能力更加恶化。

解决办法就是在系统高并发的时候,好比说像淘宝双 11 的时候,当天可能成天系统都处于一种极限的高并发访问压力之下,这时候就能够将确认收货、评价这些非核心的功能关闭,将宝贵的系统资源留下来,给正在购物的人,让他们去完成交易。

异地多活

咱们前面提到的各类高可用策略,都仍是针对一个数据中心内的系统架构,针对服务器级别的软硬件故障而言的。但若是整个数据中心都不可用,好比说数据中心所在城市遭遇了地震,机房遭遇了火灾或者停电,这样的话,无论咱们前面的设计和系统多么的高可用,系统依然是不可用的。

为了解决这个问题,同时也为了提升系统的处理能力和改善用户体验,不少大型互联网应用都采用了异地多活的多机房架构策略,也就是说将数据中心分布在多个不一样地点的机房里,这些机房均可以对外提供服务,用户能够链接任何一个机房进行访问,这样每一个机房均可以提供完整的系统服务,即便某一个机房不可以使用,系统也不会宕机,依然保持可用。

异地多活的架构考虑的重点就是,用户请求如何分发到不一样的机房去。这个主要能够在域名解析的时候完成,也就是用户进行域名解析的时候,会根据就近原则或者其余一些策略,完成用户请求的分发。另外一个相当重要的技术点是,由于是多个机房均可以独立对外提供服务,因此也就意味着每一个机房都要有完整的数据记录。用户在任何一个机房完成的数据操做,都必须同步传输给其余的机房,进行数据实时同步。

数据库实时同步最须要关注的就是数据冲突问题。同一条数据,同时在两个数据中心被修改了,该如何解决?为了解决这种数据冲突的问题,某些容易引发数据冲突的服务采用相似MySQL 的主主模式,也就是说多个机房在某个时刻是有一个主机房的,某些请求只能到达主机房才能被处理,其余的机房不处理这一类请求,以此来避免关键数据的冲突。

总结

除了以上的高可用架构方案,还有一些高可用的运维方案:经过自动化测试减小系统的Bug;经过自动化监控尽早发现系统的故障;经过预发布验证发现测试环境没法发现的Bug;灰度发布下降软件错误带来的影响以及评估软件版本升级带来的业务影响等等。

相关文章
相关标签/搜索