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

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

引言

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

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

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

无所不在的失败场景

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

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

硬件问题

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

软件bug

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

配置变更错误

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

系统恶化

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

超预期流量

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

外部攻击

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

依赖库问题

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

依赖服务问题

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

如何面向失败设计

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

冗余设计避免单点故障

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

面向失败的宏观多活架构

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

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

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

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

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

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

自动化运维管控

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

精细化的监控体系

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

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

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


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

石锤!今年Python要过苦日子了? 程序员:我疯了!

Python的好日子到头了?Python终于要回归现实了?所有程序员,刚刚一份报告把Python的真相撕开了!不信你看:Python今年要跑路?三份报告炸出真相....「人生苦短,钱多事少,快用Python」&a…

安装 kivy

系统:Windows10 64位 python 3.7.6 最好管理员身份打开 命令行窗口pip安装 kivy 依赖 ——在 windows 命令行中,执行以下命令 pip3 install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew -i http://pypi.douban.com/simple --trusted-h…

Java-数组的声明与创建

public class ArrayDemo01 {// 变量的类型 变量的名字 变量的值;public static void main(String[] args) {// 数组定义方式有两种,但是推荐第一个int[] nums; // 1. 声明一个数组 // int nums1[];nums new int[10]; // 2. 创建一个数组// …

云上快速搭建Serverless AI实验室

Serverless Kubernetes和ACK虚拟节点都已基于ECI提供GPU容器实例功能,让用户在云上低成本快速搭建serverless AI实验室,用户无需维护服务器和GPU基础运行环境,极大降低AI平台运维的负担,显著提升整体计算效率。 如何使用GPU容器实…

十分钟上手 ES 2020 新特性

作者 | 浪里行舟责编 | 郭芮ES2020 是 ECMAScript 对应 2020 年的版本。这个版本不像 ES6 (ES2015)那样包含大量新特性。但也添加了许多有趣且有用的特性。本文的代码地址:https://github.com/ljianshu/Blog本文以简单的代码示例来介绍 ES2020新特性。这样&#xff…

时延敏感业务低概率超时问题分析

前言 作为阿里云底层提供的基础设施,内部的物理网络和许多网络产品在数据平面给客户的可操作性并不高,从一定程度上来说是个黑盒。当然,在传统的IDC环境,业务和物理网络之间也存在同样的隔阂。所以在遇到业务卡顿、延迟、不通等问…

Java-数组 三种初始化及内存分析

声明的时候数组并不存在,创建的时候数组才真正的存在 数组初始化 除了八大基本类型,其他都是引用类型 public class ArrayDemo02 {public static void main(String[] args) {// 静态初始化: 创建 赋值int[] a {1,2,3,4};System.out.print…

十分钟上线 - 函数计算构建支付宝小程序的后端

阿里云函数计算服务(FunctionCompute,FC)是一个事件驱动的全托管计算服务。通过函数计算与云端各个服务的广泛集成,开发者只需要编写函数代码,就能够快速地开发出弹性高可用的后端系统。接下来我们使用FC,来快速实现一个图片转换服…

用Java开发自己的Kubernetes控制器,想试试吗?

作者 | Nicolas Frnkel译者 | 天道酬勤 责编 | 徐威龙封图| CSDN 下载于视觉中国在本文中,我们将开始开发自己的Kubernetes控制器。 技术栈可以是Python、NodeJS或Ruby。因为这个博客被命名为为“ Java极客”,因此选择Java是很正常的。 作为一个用例&…

SpringBoot 扫描包

文章目录1. 默认扫描2.指定扫描3.指定扫描21. 默认扫描 默认扫描: 在启动类WikiApplication上的SpringBootApplication注解,默认SpringBoot 扫描范围是当前包(com.gblfy.wiki)以及子包controller包等等 2.指定扫描 扫描项目包但不能扫描第三方的包&a…

揭秘阿里云背后神秘而富有能量的一群人

作为某创业公司CTO兼CTO兼CFO,带领众子弟行走于云端计算,累计犒赏已达757157.09银两,江湖人称紫龙,就是众多阿里云大使中低调内敛的一位。其话不多,一个典型的技术男,但又热心钻研传播推广,不到…

Java-数组下标越界及小结

https://www.bilibili.com/video/BV12J41137hu?p54&spm_id_frompageDriver

如何给女朋友解释什么是撞库、脱库和洗库?

来源 | 漫话编程最近,安全圈又有一个大新闻,微博名为安全_云舒的微博用户在发文称:“很多人的手机号码泄露了,根据微博账号就能查到手机号……已经有人通过微博泄露查到我的手机号码,来加我微信了。”并且,…

OceanBase数据库实践入门——性能测试建议

概述 本文主要分享针对想压测OceanBase时需要了解的一些技术原理。这些建议可以帮助用户对OceanBase做一些调优,再结合测试程序快速找到适合业务的最佳性能。由于OceanBase自身参数很多、部署形态也比较灵活,这里并没有给出具体步骤。 数据库读写特点 …

Istio 在阿里云容器服务的部署及流量治理实践

目标 在阿里云容器服务 Kubernetes 集群上部署 Istio 服务网格实践灰度发布、故障注入、熔断等 Istio 流量管理特性 准备工作 安装和设置 kubectl 客户端,请参考不同的操作系统,如果已经安装请忽略: macOS curl -LO https://kubectl.oss-cn…

mysql创建操作用户

使用root用户创建一个新的数据库wiki 创建一个新的连接 由于新建的用户名下没有表,因此会抛出异常 就好了

Java-数组的使用

public class ArrayDemo03 {public static void main(String[] args) {int[] arrays {1,2,3,4,5};// JDK1.5, 没有下标,增强写法 // for (int array : arrays) { // System.out.println(array); // }printArray(arrays);Syste…

为何你的 SaaS 想法总是失败?没想清楚这 4 个原因可能会继续失败!

作者 | Elliot Bonneville译者 | 天道酬勤 责编 | 徐威龙封图| CSDN 下载于视觉中国最初,作者是准备进行一个”7 天 SaaS 挑战“的,但当他真正坐下来的时候就面临了第一个问题:他还没有决定要做什么。不过幸好的是,作者有一个完整…

重磅开源|AOP for Flutter开发利器——AspectD

问题背景 随着Flutter这一框架的快速发展,有越来越多的业务开始使用Flutter来重构或新建其产品。但在我们的实践过程中发现,一方面Flutter开发效率高,性能优异,跨平台表现好,另一方面Flutter也面临着插件,…