为什么说优秀架构师往往是一个悲观主义者?

简介: 18年前,200家企业由于在事故中信息系统遭到严重破坏而永远地关闭了。

阿里妹导读:18年前,200家企业由于在事故中信息系统遭到严重破坏而永远地关闭了。这样的事故引发了后人深思,对于工程师而言,不仅要求设计的系统足够强壮,还需要具备考虑失败的能力,当失败场景悉数被考虑周全、并且结合充分的演练,一切会不会不一样?我们熟知面向对象设计和面向程序设计,阿里巴巴资深技术专家游骥洞悉行业现状,抛出了一个新模式——面向失败设计。今天,听他娓娓道来,如何在一开始的系统设计阶段就考虑到各种失败场景,把面向失败当成是系统设计的一部分,准备好从失败中恢复的策略。

引言

一个优秀的架构师通常都是一个悲观主义者,除了设计好能够支撑业务持续发展的优雅架构,另一个容易被忽略的重要能力在于充分考虑失败场景。如果对失败场景考虑不够充分,轻则出现业务不可用,影响用户体验和企业声誉;重则导致数据永久丢失、业务再无恢复可能。

2001 年 9 月 11 日,美国世贸中心双子大厦遭受了谁也无法预料的恐怖打击,灾难发生前约有 350 家企业在世贸大厦中工作,事故发生一年后,重返世贸大厦的企业变成了 150 家,有200 家企业由于重要信息系统的破坏,关键数据的丢失而永远关闭、消失了,其中的一家公司声称自己要恢复到灾难前的状态需要 50 年的时间。

image

“Everything fails, all the time”,无论是在传统软件时代还是在互联网、云时代,系统终究会在某个时间点失败,面向失败的设计理念数十年来并没有多大的变化,不同的是在分布式、云架构的互联网时代:失败将由小概率偶发事件变成常态,同时应对和处理失败的具体实现方式也大相径庭。

无所不在的失败场景

单个技术点在绝大部分时间都能按照设想正常工作,但是当规模和复杂度到达一定程度,失败其实无所不在。当你的业务场景从服务企业内部的几百号员工变成面向上亿的外部用户,你不确定你的用户群会有些什么样的角色,也不知道他们会在你的系统平台上创造出什么样的业务行为;当你的技术框架从单机、一体机演进到分布式的多层、多组件架构,原本5个以内的技术组件可能变成了今天的500个,并且为了用较低的成本保持服务能力的扩展能力,你可能放弃了稳定性更好但也昂贵的商业技术、转而用开源自建来替代。

互联网业务快速发展不仅直接带来了流量、安全等不确定性,同时促使了技术架构的快速演进,使架构变得越来越复杂,这些因素都将导致失败发生的概率大幅提升。当人类的工作、生活越来越依赖互联网,一旦出现失败,造成的影响和损失将是空前巨大的。在远古时代,人类没有自来水也没有电,一切都很好;今天如果停电停水一段时间,相信很多人都会无法适应,而互联网正在逐步演变成跟水和电一样的基础设施。失败的原因多种多样,抽象来看可以分为以下几类:

硬件问题

首先,硬件是有生命周期的,它一定会老化,并且你不知道它会在什么时候坏;其次,硬件是一个实体,它存在于客观环境当中,它的状态会受外部环境干扰,比如火灾、地震等外力因素都可能导致硬件损坏;最后,所有硬件都会存在残次品,你很可能就是那个不幸者。通常情况下单个硬件出问题的概率不高,但是当有几十万的硬件设备,硬件的失败问题每天都会发生。

image

软件bug

即便是最优秀程序员写出来的程序,经过最优秀测试同学的严格测试后的代码,上线依然无法做到完全没有bug。互联网业务迭代往往讲究一个“快”字,以往几个月或者几年升级一次的软件程序,现在一周就需要升级一次或者多次,这大幅提升了软件出错的可能性。

配置变更错误

系统运行态的日常运维过程当中,难免会因为疏忽或者考虑不周全导致灾难。当上万名技术同学跟上百个变更系统做笛卡尔积,哪怕是6个9的可靠性,依旧无法做到万无一失。全局的流量入口、权限与安全验证体系、统一网关与接口平台等技术环节是可能促发全站不可用的重要风险点,对于影响面大的配置的变更需要尤为谨慎。

系统恶化

原本工作得很好的程序随着时间的推移可能有一天不再正常工作,举几个常见的例子:自增变量运行了很长一段时间后出现越界、缓存随着数据量的逐渐变大而出现空间不足、数据库连接池随着机器的扩容而不够用等等。千万不要认为运行良好的系统是不会出问题的,它的代码里面可能藏了定时炸弹,只是你不知道会在什么时间点爆炸。

超预期流量

某一天你的系统可能突然会承受远超过预期的每秒请求数,特别是在“中国特色”的互联网场景之下,你很难精确预估系统各个时间点的业务访问量。

外部攻击

你需要考虑各种攻击行为,包含流量攻击和安全攻击。你的系统可能随时会面临着DDOS和CC类攻击,你传输的数据可能会被盗取或者篡改。

image

依赖库问题

你的系统很可能会用大量的二方库或者三方库,它们对你来说是黑盒子,你不了解它们存在哪些风险,并且你无法掌控。这些库可能会存在漏洞、可能会有bug,可能会大量消耗你的系统资源,总之不要太信任它们。

依赖服务问题

你依赖的服务也一定不会100%可用,它们可能会超时,可能会失败。当依赖服务超时的时候,如果你没有很好地处理,可能会导致你自己的系统无法工作,在分布式场景下,这种失败状态会持续辐射,最终导致大面积的不可用。

如何面向失败设计

作为一个悲观主义者,你需要在一开始的系统设计阶段就考虑到以上各种失败场景,把面向失败当成系统设计的一部分,并且准备好从失败中恢复的策略,这有助于更好地提升整个系统的可用性。只有你意识到事情会随着时间的推移而失败,并将这种思想融入到体系结构中,那么在失败发生的时候你才能完全不受影响或者将失败损失降到最低。面向失败的设计理念数十年来并没有多大的变化,一些好的经典原则在今天依旧被广泛运用。

image

冗余设计避免单点故障

硬件和软件都不可靠,环境和人都存在极大的不确定性,虽然无法避免失败场景的发生,但是可以通过冗余设计来规避局部失败对系统的影响。冗余设计避免单点故障这一策略在互联网技术架构中处处可见,比如重要的服务通常都会部署多个、数据库的主备结构、服务调用的重试机制、存储的多副本等概念都属于这一范畴。

面向失败的宏观多活架构

除了局部失败场景,你的系统可能还面临着大范围的失败场景。大范围的原因有两个:天灾,比如火灾、地震、台风、雷电等大的自然灾害可能导致大面积的基础设备被毁坏;人祸:人的失误或者刻意破坏行为有时候也会酿成大祸,如操作错误、破坏、植入有害代码和恐怖袭击。“面向失败的宏观多活架构”从宏观架构的高可用层面来解决系统的整体可用性问题,随着技术的演进,冷备、热备、两地三中心、异地多活等应对大范围失败场景的技术体系这些年频频被提起。

服务能力与依赖调用自我保护

如何来衡量一个软件系统的设计是否优良?一条很重要的衡量标准——在任何情况之下你的软件系统都应该工作在当前环境的最优状态。每个人都知道机翼是飞机的重要部件,一旦机翼出现问题,飞机很可能就会坠落。然而在二战当中,许多战斗机即便机翼千疮百孔了,依然保持着最佳战斗能力;甚至还有更夸张的情况:1983年的一次战斗机演习当中,一架飞机由于事故损失了一个机翼,这架缺少一个机翼的飞机依然保持了飞行能力、最终完成安全着陆。

软件系统由两部分构成:系统自身的代码和依赖的库以及服务。“服务能力与依赖调用自我保护”需要从这两块分别切入构建系统在任意情况都始终工作在最佳状态的能力。服务限流、系统负载保护、给依赖的服务设置超时或者资源限制等都是相应的应对策略。

image

为一切不可预料的情况备好预案

能够抵抗失败和从失败中快速恢复是面向失败设计的核心思想,然而即便已经做了万全的设计,也并非所有的失败场景都是系统能够自动抵御的。你需要考虑到所有的失败场景,并准备好相应的应对预案。为一切不可预料的情况备好预案才能在失败场景真正发生时做到有条不紊。做好预案需要对失败场景有全面的考虑:会发生哪些失败?失败会带来什么问题?应对策略是什么?预期的恢复时间多久?恢复后的影响面有多大?需要通知到哪些角色?等这一系列的因子构成了一个完整的预案体系。

自动化运维管控

大量的系统故障是因为人的失误造成的,即便让一个优秀的运维工程师进行一万次同样的运维操作也难免不出错。唯一的解决办法便是在运维过程当中尽可能降低人为操作的比重。系统化、白屏化是第一个阶段——将人为的操作步骤固化成系统程序,避免操作失误;自动化以及智能化是第二个阶段——将正确的决策过程也固化成智能程序,避免决策失误。同时所有的运维动作都需要遵循灰度原则,做到可灰度、可监测、可回滚,即便出现了失误也能控制好爆炸半径,并且做到快速恢复。

精细化的监控体系

面向失败设计不仅要求你的系统足够健壮,同时要求你能够在第一时间感知到失败的发生。无论是自动化的系统恢复,还是人为介入,如果你压根都不知道是哪里出问题了,一切都将束手无策。精细化的监控体系一方面能够在出现问题的时候以最快的速度将最准确的信息传递到人或者运维系统,同时它还能够展现趋势、进行提前预警。AI技术的结合使得监控领域在近几年得到了新的发展驱动力:智能监控报警、根因定位、智能预测、智能决策等能力都是学术界和工程界非常热衷的课题。

image

故障与攻防演练锤炼容灾应急能力

最后,即便以上工作都做好了,你也不能高枕无忧去等待失败到来。你的设计、系统、流程、技术人员等需要通过不断演练,来保障能力和进化升级。对于代价非常巨大的事件,做好前期的充分演练是非常有必要的,比如军事演练、消防演练等都属于这一范畴。而系统不可用的代价对于企业来讲很可能是无法承受的,因此需要在平时做好充分的演练:通过故障与攻防演练锤炼容灾应急能力,对面向失败的设计做好充分验证。只有当所有的失败场景都被提前演练过,当失败真正来临时才能做到胸有成竹。

原文发布时间为: 2019-06-18
本文作者: 游骥
本文来自云栖社区合作伙伴“ 阿里技术”,了解相关信息可以关注“ 阿里技术”。

相关文章
|
架构师 Java 大数据
为什么说优秀架构师往往是一个悲观主义者?| 开发者必读(001期)
最炫的技术新知、最热门的大咖公开课、最有趣的开发者活动、最实用的工具干货,就在《开发者必读》! 每日集成开发者社区精品内容,你身边的技术资讯管家。
75492 0
|
6天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
4天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
15天前
|
弹性计算 Kubernetes Cloud Native
云原生架构下的微服务设计原则与实践####
本文深入探讨了在云原生环境中,微服务架构的设计原则、关键技术及实践案例。通过剖析传统单体架构面临的挑战,引出微服务作为解决方案的优势,并详细阐述了微服务设计的几大核心原则:单一职责、独立部署、弹性伸缩和服务自治。文章还介绍了容器化技术、Kubernetes等云原生工具如何助力微服务的高效实施,并通过一个实际项目案例,展示了从服务拆分到持续集成/持续部署(CI/CD)流程的完整实现路径,为读者提供了宝贵的实践经验和启发。 ####
|
5天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
15 1
服务架构的演进:从单体到微服务的探索之旅
|
3天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
23 5
|
6天前
|
监控 API 微服务
后端技术演进:从单体架构到微服务的转变
随着互联网应用的快速增长和用户需求的不断演化,传统单体架构已难以满足现代软件开发的需求。本文深入探讨了后端技术在面对复杂系统挑战时的演进路径,重点分析了从单体架构向微服务架构转变的过程、原因及优势。通过对比分析,揭示了微服务架构如何提高系统的可扩展性、灵活性和维护效率,同时指出了实施微服务时面临的挑战和最佳实践。
25 7
|
5天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
19 5
|
5天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
6天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?