-->

后端面试38讲_32_29_高可用架构我们为什么感觉不到淘宝应用升级时的停机

你好,我是李智慧。

十几年前我参加阿里巴巴面试的时候呢,觉得阿里巴巴这样的网站web应用开发简直是小菜。

因为我之前是做类似于tom cat这样的web容器开发的,确实面试的时候信心满满。

确实面试官前面的问题都是关于数据结构操作系统设计模式的,也就是我们这个专栏模块一和模块二的内容。

我感觉自己回答的还不错,所以信心更加满满。

这个时候面试官忽然提了一个问题,我们的web程序每个星期都会发布一个版本,但是程序要求七乘二十四小时可用。

也就是说啊启动新版本程序替换老版本进行程序升级的时候,程序还在对外提供服务。

用户没有感觉到停机,我们是怎么做到的呢?应用程序升级必须要用新版本的程序包代替老版本的程序包,并重新启动程序。

这段时间呢程序是不能对外提供服务的,用户请求一定会失败。

但是阿里巴巴让这段时间的用户请求依然是成功的。

打个比方,就是要在飞机飞行过程中更换发动机,还不能让乘客感觉到这个问题当时完全不在我的知识范围之内。

但是我知道这个需求场景是真实存在的,而且确实应该是可以做到的。

但是我完全不知道是怎么做到的。

面试官看我瞠目结舌,笑着问,我想不想知道答案,我立刻回答说,想知道。

结果面试官跟我说,加入我们团队你就知道了,这其实是一个关于互联网应用高可用的问题。

我们知道啊,外b应用在各种情况下都有可能是不可访问的,各种硬件故障等等。

应用服务器以及数据库崩机,以络交换机、宕机、磁盘损坏、网卡松掉等等。

还有各种软件故障程序,bug什么的,就算没有bug,程序要升级,必须要关闭程序,重新启动。

这段时间内呢应用也是不可用的。

此外,还有外部环境引发的不可用,比如促销引来大量用户访问,导致系统并发压力太大而崩溃,以及黑客攻击、机房、火灾、挖掘机挖掘、管缆等等各种情况导致的应用不可用。

而互联网的高可用是说在上面的各种情况下,应用都要是可用的用户都能够正常访问系统,完成业务处理,这似乎是不可能的任务。

首先我们要看一下什么叫做应用的高可用以及可用性。

如何度量业界通常用多少个九来说明互联网应用的可用性。

比如说淘宝的可用性是四个九,就是说淘宝的服务百分之九十九点九九可用。

这句话的意思是,淘宝的服务要保证在所有的用行时间里只有百分之零点零一不可用。

也就是说一年大概有五十三分钟,不可用。

这个百分之九十九点九九就叫做系统的可用性指标。

这个值的计算公式是这样子的,可用性等于一减,年度不可用时间除以年度的总时间乘以百分之一百。

一般说来呢,两个九表示,系统基本可用年度不可用,时间小于八十八小时。

三个九是较高,可用年度不可用,时间小于九小时。

四个九是具有自动恢复能力的高可用,年度不可用,时间小于五十三分钟。

五个九是指极高的可用性,年度不可用,时间小于五分钟。

我们熟悉的互联网产品的可用性大多是四个九,淘宝、百度、微信差不多都是这样。

下面我们会讨论各种高可用技术方案。

但是不管哪种方案实现高可用,需要投入的技术和设备成本都是非常高的。

因此,可用性并不是越高越好,而是要根据产品的策略,寻找高可用投入产出的最佳平衡点。

像支付宝这样的金融产品,就可能需要更高的可用性,而微博的可用性要求就相对低一些。

像对的,支付宝的可用性是超过百分之九十九点九九的,而twitter的可用性只有百分之九十八。

可用性指标是对系统整体可用性的一个度量。

在互联网企业中呢,为了更好的管理系统的可用性鉴定好系统故障以后的责任通常会用故障分进行管理。

一般的过程是根据系统可用性指标换算成一个故障分。

这个故障分是整个系统的故障,分比如十万分,然后根据各自团队各个产品各个职能角色出现可责任不同,把故障分发给下面的每一个团队。

每个人。

也就是说,每个工程师在年初的时候就会收到一个预计的故障分。

然后每一次系统出现可用性故障的时候,都会进行故障考核,划定到具体的团队和责任人以后,和扣除他们的责任。

分到了年底的时候,如果一个工程师的故障分为负分,那么很有可能会影响它的绩效考核。

而系统的高可用架构,就是要在上述的各种故障情况下,保证系统依然可以提供服务。

具体包含以下几种方案,我们已经在前面几篇架构专栏中提到了这些架构方案。

这里我们从高可用的视角重新审视一下,这些架构是如何实现高可用的。

首先我们从冗余备份的角度讲起,既然各种服务器故障是不可避免的,那么架构设计上就要保证当服务器故障的时候,系统依然可以访问。

具体上讲就是要实现服务器的冗余备份。

冗余备份时说,提供一个服务的服务器要存在冗余,即任何服务都不能只有一台服务器,服务器之间要互相进行备份。

任何一台服务器出现故障的时候,请求可以发送到备用的服务器上面去。

这样即使某台服务器失效,在用户看来,系统依然是可用的讲的负载均衡架构。

这篇文章中讲的通过负载均衡服务器,将多台应用服务器构成一个集群,共同对为提供服务。

这样可以利用多台应用服务器的计算资源,满足高并发的用户访问请求。

事实上,负载均衡还可以实现系统的高可用。

这里在文稿中有同事可以参考负载均衡服务器,通过心跳检测发现集群中某台应用服务器失效。

然后负载均衡服务器就不将请求分发给这台服务器。

对用户而言,也就感觉不到服务器失效,系统依然可用。

回到我们开头的问题。

阿里巴巴就是用这种方式实现的应用程序升级的时候停止应用进程,但是不影响用户访问。

因为应用程序部署在多台服务器上,应用程序升级的时候,每次只是stop一台或者一部分服务器。

在这些机器上进行程序升级,这个时候集群中还有其他的服务器在提供服务,因此用户感觉不到服务器已经停机了。

此外,我在数据重储架构这篇文章中也讲到了数据库主组复制,这也是一种冗余备份。

这个时候不只是数据库系统,而DBMS互相进行冗余备份,数据库里的数据也要进行冗余备份。

此外,数据存储在多台服务器里保证,当任何一台服务器失效,数据库服务依然可以使用。

然后我讲一下失败隔离,这是保证系统高可用的另一个策略。

将失败限制在一个较小的范围之内,使故障影响范围不扩大。

具体实现失败隔离的主要架构技术,使消息队列。

一方面,消息的生产者和消费者通过消息队列进行隔离。

如果消费者出现故障的时候,生产者可以继续向消息队列发送消息,而不会感知到消费者的故障。

等消费者恢复正常以后,再去从消息队列中消费消息。

所以,从用户处理的视角看,系统一直是可用的发送邮件,消费者出现故障,不会影响生产者应用的运行,也不会影响发送短信等其他消费者正常的运行。

另一方面,由于分布式消息队列具有消分添股的作用,所以在高并发的时候,消息的生产者可以将消息缓冲。

在分布式消息队列中,消费者可以慢慢的从消息队列中去处理。

一、不会将损失的高并发负载压力直接施加到整个系统上,导致系统崩溃。

也就是将压力隔离开来,使消息生产者的访问压力不会直接穿移到消息的消费者,这样可以提高数据库等对压力比较敏感的服务器的可用性。

同时,消息队列还使得程序解耦,将程序的调用和依赖隔离开来。

我们知道,利耦合的程序更加易于维护,也可以减少程序出现bug的几率。

接着我讲一下限流降级的事角,这也是保护系统高可用的一种手段。

在高并发的场景下,如果系统的访问量超过了系统的承受能力,可以通过限流对系统进行保护。

限流是指对进入系统的用户请求进行流量限制。

如果访问量超过了系统的最大处理能力,就会丢弃一部分的用户请求,保证整个系统可用,保证大部分的用户是可以访问系统的。

这样虽然有一部分用户的请求被丢弃,产生了部分的不可用,但是还是好或整个系统崩溃,所有的用户都不可用。

要好降级是保护系统的另一种手段。

有一些系统功能是非核心的,但是它也会给系统产生巨大的压力。

比如说在电商系统中有确认收货这个功能,即使我们不去确认收货,系统也会超时自动确认收货。

但是实际上确认收货这个操作是一个非常重的操作,因为他会对数据库产生很大的压力。

我要进行更改订单状,能完成支付,确认并进行评价的一系列操作。

如果在系统高并发的时候就完成这些操作,那么就会对系统雪上加霜,使系统的处理能力更加恶化。

解决办法呢就是在系统高并发的时候,比如说像淘宝双十一的时候,当天可能整天系统都处于一种极限的高并发。

访问压力之下,这个时候就可以将确认收货评价这些非核心的功能关闭,将宝贵的系统资源留下来给正在购物的,让他们去完成交易。

他们前面提到的更种高可用策略,都还是针对一个数据中心内的系统架构,针对服务器级别的软硬件故障而言的。

但是如果整个数据中心都不可用,比如说数据中心所在的城市遭遇了地震,即房遭遇了火灾或者停电。

这样的话,不管我们前面的设计和系统多么的高可用,系统依然是不可访问的。

为了解决这个问题,同时也为了提高系统的处理能力,改善用户体验。

很多大型互联网应用都采用异地多活的多机房架构策略。

也就是说啊将数据中心分布在多个不同地点的机房里。

这些机房呢都可以对外提供服务,用户可以连接到任何一个机房进行访问。

这样每个机房都可以提供完整的系统服务。

即使每个机房不可使用,系统也不会宕机,依然保持高可用。

异地多活的架构。

考量的重点是用户请求如何分发到不同的机房去。

这个主要可以在域名解析的时候完成,也就是用户进行域名解析的时候,会根据就近原则或者其他的一些策略,采用用户请求的分发。

另一个至关重要的技术点时,因为多个机房都可以独立的对外提供服务。

那么就意味着每个机房都要有完整的数据记录。

用户在任何一个机房完成的数据操作,都必须同步传输给其他的机房,进行数据实时同步,数据库实时同步。

最需要关注的就是数据冲突问题。

同一条数据,如果在两个数据中心被修改了,该如何解决呢?为了解决这种数据冲突的问题,某些容易引起数据冲突的服务,采用类似于mysql的主组模式。

也就是说啊,多个机房在某一时刻,只有一个是主机房,某些请求只能到达主机房才能被处理。

其他的机房不处理这一类请求,以此来避免关键数据的冲突。

除了以上的高可用架构方案,还有一些高可用的运维方案。

通过自动化测试,减少系统的bug,通过自动化监控,尽早发现系统的故障。

通过预发布验证,发现测试环境无法发现的bug.通过灰度发布降低软件错误带来的影响,以及评估软件版本升级带来的业务影响等等。

预发布验证呢就是将一台线上生产环境的服务器当做预发布服务器。

在进行应用升级的时候,先在预发布服务器上进行升级软件工程师访问这台服务器验证系统,正常后再发布到其他服务器上发布。

在这台预发布服务器上的应用,即使存在bug,微博用户也不会感觉到。

这是为什么呢?什么样的bug是测试环境不能发现,而需要到预发布服务器上才能发现的呢?欢迎你在评论区写下你的思考,也欢迎把这篇文章分享给你的朋友,或者同事一起交流一下。