再好的技术,再完美的规章,也无法取代人自身的素质和责任心

2020 年 3 月 16 日

再好的技术,再完美的规章,也无法取代人自身的素质和责任心

海恩法则


德国人帕布斯·海恩提出一个在航空界关于飞行安全的法则: 每一起严重事故的背后,必然有 29 次轻微事故和 300 起未遂先兆以及 1000 起事故隐患,这个法则即是著名的海恩法则。猜想在飞行安全领域,海恩也是通过统计学的方法发现的这一法则,不然为什么是 1:29:300:1000 这样的比例呢?


和海因里希法则一样,在其他领域的安全生产仍然有借鉴意义。我们来看 2 个案例,得以管窥一二。


东方网 2016-11-25 09:15 报道,截止 11 月 24 日早 7 时左右,江西省丰城市国电丰城电厂三期在建项目冷却塔施工平桥吊倒塌,事故死亡人数已上升至 67 人。记者还发现,该公司近年曾发生多起工人死伤的安全事故。那么,试问一家频发安全事故的公司为何还在正常经营,每次事故发生后又做了哪些改进措施?


大众日报于 2012 年曾报道过岱山县一个蓄水 18 万立方米的水库突然溃坝,洪水瞬间冲毁村庄。当地已确认遇难 10 人,27 人受伤。多名村民接受多家媒体采访时反映,早在 50 天前,水库已经出现裂缝漏水,村民向当地政府反映了不止一次,但一直没人来修。有村民告诉记者,就在事发前一天,还有人去镇政府反映情况。在 8 月 7 日,岱山县三防指挥部在台风“海葵”到来前还曾信誓旦旦地称,岱山县水利部门已对全县水库、山塘、海塘等水利设施进行了全面检查,确保“危险水库空库运行”,“24 小时值班,加密巡查频率,对水库安全运行情况进行密切监测,确保不因水利设施因素造成人员伤亡”。



别再用事故去验证海恩法则了,没有切实的措施或者防患于未然,或者对隐患的采取行动,发什么誓都没有用。“海恩法则”核心理论有二:一是事故的发生是量的积累的结果;二是再好的技术,再完美的规章,在实际操作层面,也无法取代人自身的素质和责任心。


回到软件行业,海恩法则和海因里希法则有非常好的指导意义。我们稍微回溯一下自己手头发生的,看到的,见到的系统故障,无不是因为所谓的简单、低级问题到导致大故障。


代码拷贝之祸


小明看到张三的代码刚好是实现了他想要的功能,于是就拷贝过来使用了。不曾想,上线之后,消息被张三负责的系统服务器接收去了,因此拷贝代码未正确修改事件标识。同时,笔者也见过另外一个拷贝代码的案例,导致金额错误的膨胀到 100 倍,因为拷贝者把多个 processor 的顺序搞反了,而让代码实际运行超出预期。拷贝无小事,必须让代码成为自己身体的一部分,足够了解。这 2 个案例都有很多种方法去发现问题而不至于让故障流入线上,质量防线一再失守,值得深思。除了可能的技能问题,态度和意识是首要问题。


未正确处理的返回值或异常


一般公司的编码规范都会涉及异常的正确处理问题。比如业务异常,系统重试;系统内部异常,返回失败;明确抛出异常和空字符串 NULL 的区别,明确抛出异常和返回数字 0 的区别等等。被调用方本应该抛出异常,结果返回了 0,那么调用则继续按照正常的业务逻辑进行处理,就会发生超出预期的事情,比如本应扣款的账户却未扣款而产生资损。


GITLAB 误删除数据库事件


前一段,Gitlab.com 发生了一个大事,某同学误删了数据库,这个事看似是个低级错误,不过,因为 Gitlab 披露了整个处理过程,还直播了恢复过程,因此可以学习到更多的内容。一个叫 YP 的同学在给 Gitlab 的线上数据库做一些负载均衡的工作,在做这个工作时的时候突发了一个情况,Gitlab 被 DDoS 攻击,数据库的使用飙高,在 block 完攻击者的 IP 后,发现有个 staging 的数据库(db2.staging)已经落后生产库 4GB 的数据,于是 YP 同学在 Fix 这个 staging 库的同步问题的时候,发现 db2.staging 有各种问题都和主库无法同步,在这个时候,YP 同学发现 db2.staging 都 hang 在那里,无法同步,于是他想把 db2.staging 的数据库删除了,这样全新启动一个新的复制,结果呢,删除数据库的命令错误的敲在了生产环境上(db1.cluster),结果导致整个生产数据库被误删除。更悲催的事情发生了,在恢复的过程中,他们发现只有 db1.staging 的数据库可以用于恢复,而其它的 5 种备份机制都不可用。具体备份失败的原因,按 Gitlab 在 docs.google.com 披露的原因,备份失败原因如下,5 种备份机制为:LVM 快照、常规备份、自动同步、Azure 备份、S3 备份。



LVM 快照在默认情况下每 24 小时做一次。在故障发生前大概 6 小时,YP 正好手动运行了一次。


  • 常规备份似乎也是每24小时做一次,不过YP还未能查清楚它们存储在何处。据JN声称,这些似乎未奏效,只生成了几个字节大小的文件。原因是pg_dump时效,PostgreSQL版本问题导致。

  • Azure备份失效:已为NFS服务器启用了Azure中的磁盘快照,但是没有为数据库服务器启用Azure中的磁盘快照。

  • 一旦将数据同步到试运行环境,同步过程就消除Web勾子(webhook)。除非我们可以在过去的24小时内从常规备份中获取这些数据,否则它们将丢失殆尽。

  • 我们备份到S3的内容显然也没有奏效:存储桶(bucket)空空如也。

  • 复制程序很不可靠,容易出错,依赖几个随机性的外壳脚本,而且缺少完备的说明文档。


具体的恢复过程先不追溯,但从 5 种备份机制都不可用就能发现巨大问题,不可用不是今天才发生的,而是长期以往就是如此。不可用的备份就是形同虚设。如何保障可用,如何衡量可用是生产备份过程中不得不做的事情。无独有偶,银行业必须做到的“两地三中心”如何衡量单机房故障之后的可用性,或者部分业务的可用性,没有全局分析、制定应急措施、持续演练,两地三中心在机房故障的时候无法发挥作用。



如图所示,游乐场的这根绳子是其保护作用的,相当于一道防线。但是如果不关注它的可用性,是要出问题的。


日本瑞穗证券公司经纪人操作失误


2005 年 12 月 8 日,日本瑞穗证券公司的一名经纪人在交易时出现重大操作失误,引发投资者恐慌并导致证券类股票遭遇重挫,东京证券交易所陷入一片混乱。而瑞穗证券已经因为这一数字输入错误在 16 分钟之内蒙受了高达 270 亿日元(约合 18.5 亿人民币)的损失,造成日本证券交易史上前所未有的重大事故。瑞穗证券公司一名经纪人接到一位客户的委托,要求以 61 万日元(约合 4.19 万人民币)的价格卖出 1 股 J-Com 公司的股票。



然而,这名交易员却犯了个致命的错误,他把指令输成了以每股 1 日元的价格卖出 61 万股。这时操作屏上市场价格栏中出现了输入有误的警告,但由于这一警告经常出现,操盘手忽视警告继续操作。随后,东京证交所发现错误,电话通知瑞穗证券公司操盘手立即取消交易,但取消交易操作未能成功。


一个重大故障,仅仅是一个警告指令而不能中止交易发布,是否正常?从海恩法则推导,一次重大故障会有 N 次小故障的暴露,那么对于金融行业,比例关系会有新的定义,可能很少有小故障,行业的特殊性决定。


如果进一步分析,该案例涉及到瑞穗证券公司相关工作人员疏忽、东京证券交易所系统存在缺陷且未能及时采取措施等问题。比如这样一个数量和价格均异常的交易委托能够顺利进入交易所交易系统而未被拒绝,其原因是该系统对此没有做前端检查。从质量角度看,工作人员不出问题的质量防线相当脆弱,而第二道质量防线即系统前端检查放弃,则无异于大门洞开,风险一直存在。


爱国者导弹误差


在美伊战争期间,有一沙漠盾牌行动,美军部署了爱国者导弹系统来拦截伊拉克的飞毛腿导弹。跟踪爱国者导弹的软件使用目标速度和当前时间,预测目标每一秒的位置。因为各种不同目标最大速度可能达到 5 马赫,这些计算必须相当精确。不幸的是雷达定位软件有一个致命缺陷,系统长时间运行之后,内部时间会不准,则影响对于目标物体的拦截,可能实际上目标物体进行了指定范围的攻击,但爱国者导弹系统发现不了,因为它锁定的范围是偏差的,此之谓差之毫厘谬以千里。


在 2.26 日这天,爱国者导弹系统运行了 100 个小时。当一枚伊拉克导弹锁定美国在沙特达兰的一处空军机场发射导弹时,爱国者导弹系统监测到了这一切。但在这个时刻,其内部时间误差达到 0.34 秒,所以当它尝试计算导弹下一个位置时,竟然在搜寻偏离导弹实际位置半公里多的空域。系统立即断定根本没有敌方导弹,并取消了拦截。导弹行进到了其目的地,造成 28 名士兵死亡。


如下图所示意,我们复盘一下事故的关键事件,看能有怎样的发现。



首先明确爱国者雷达系统的工作原理,拦截敌方导弹包括搜索、验证、跟踪三个环节。一旦要执行拦截动作,则有一个射程范围,会在目标物体周围炸裂为大约 1000 块碎片,这些碎片会飞入目标物体的运行轨道,破坏目标物体。


我们用时间轴来描述一下关键信息。其实早在事故前 10 几天,就有反馈关于雷达系统缺陷的报告了,但是并未引起美国军方的重视。



从上图可以看到,美国军方 2.11 有一次决策过程:认为爱国者导弹系统不会连续工作超过 8 小时,以色列军方的发现的是偶然事件。我们对照一下“海恩法则”的核心理论:


  • 事故的发生是量的积累的结果

  • 再好的技术,再完美的规章,在实际操作层面,也无法取代人自身的素质和责任心


以色列军方的发现是一次小事故的提示,可能以色列是在演习环境,未有重大后果。量的积累加上美国军方责任心不够,就导致了坏的结果。我们在软件研发中容易忽略所谓的小概率事件,不能在事件出现苗头的时候就扼杀,这和我们的责任心,意识有非常大的关系。衡量意识好不好的 2 个 tips:1 是以假设代替求证。比如我拷贝这段代码肯定是没有问题的,在 A 系统已经运行很久了;备份复制运行良好,我完全有信心。2 是能否见微知著。如果出现了异常,你假设为小概率事件,甚至说只有在某条件下才会出现而掉以轻心,则终可能酿成大祸。


意识和责任心为什么这么重要呢?


一是墨菲定律,你假设的小概率事件则外部条件发生变化的时候概率可能会大幅度增加。二是质量保障体系包括预防、监控、熔断、修复等过程,不出错是不可能的,也就是预防措施是最有效,成本最低的方式,但是又最难。更多的措施要通过监控,控制范围,快速修复来解决。


同时,2.21 日,爱国者项目组向美国军方发出警告:爱国者导弹系统如果长时间工作,射程发生偏离,追踪目标可能失败。这里有一个明显的问题就是长时间是多长?同样,军方未引起重视,再次证明一个大事故的背后是因为持续多次的人的疏忽或者系统症状未得到重视而累积而成。


本文转载自成哥的世界公众号。


原文链接:https://mp.weixin.qq.com/s/vKnSOBEdnowhnLtCfc_tvg


2020 年 3 月 16 日 20:3092

评论

发布
暂无评论
发现更多内容

10.7作业

张荣召

10.1微服务:服务本身的设计,维护及治理

张荣召

10.2微服务:落地实践的策略与思路

张荣召

JDBC【4】-- SPI底层原理解析

秦怀杂货店

Java 源码 spi

第十周总结

睁眼看世界

极客大学架构师训练营

架构师Week6作业

lggl

作业

学习总结--week10

张荣召

码了2000多行代码就是为了讲清楚TLS握手流程

新世界杂货铺

golang https 后端

一次有效的产品需求头脑风暴

Bruce Talk

敏捷开发 Agile Product Owner

10.5软件组件设计原则

张荣召

【Java基础】-- isAssignableFrom的用法详细解析

秦怀杂货店

Java 关键字

阿里P8架构师呕心沥血整理的【Docker实战】文档带你玩转Docker。

Java成神之路

Java 程序员 架构 面试 编程语言

Java程序员怎么写简历?你这样介绍项目经验面试官会对你刮目相看

Java成神之路

Java 程序员 架构 面试 编程语言

两年Java开发经验,面试字节跳动惨遭滑铁卢,努力复习54天二战字节跳动终获offer定级2-2【面试答案+复习资源】

Java成神之路

Java 程序员 架构 面试 编程语言

内推阿里,朋友说让我学会这46道面试题,我不信,现在我后悔了

小Q

Java 学习 编程 架构 面试

接口测试--接口文档规范

测试人生路

接口文档

10.4领域驱动设计DDD

张荣召

作为一个Java开发者连Spring三剑客都没吃透,你拿什么和老板谈涨薪?

Java成神之路

Java 程序员 架构 面试 编程语言

阿里P8Java架构师呕心沥血整理出来的[史上最全Java面试题精选集锦]!

Java成神之路

Java 程序员 架构 面试 编程语言

Mybatis【4】-- 关于Mybatis别名定义

秦怀杂货店

Java mybatis

架构师训练营-week10

睁眼看世界

极客大学架构师训练营

食堂就餐卡系统 UML 设计

心晴雨亦晴(~o~)

极客大学架构师训练营

Mybatis【3】-- Mybatis使用工具类读取配置文件以及从属性读取DB信息

秦怀杂货店

Java 数据库 mybatis

该怎样才能成为高薪架构师?阿里P8大牛给迷茫的程序员一些中肯建议“请不要再虚度光阴了”。

Java成神之路

Java 程序员 架构 面试 编程语言

远程面试蚂蚁金服,三面之后本以为石沉大海,没想到却被直接录取

Java成神之路

Java 程序员 架构 面试 编程语言

最佳的思维导图生成工具——markmap 使用教程

白色蜗牛

Java 程序员 职场 实用工具

架构师训练营第10周课后练习

10.3微服务网关的技术架构

张荣召

架构师训练营第十周学习总结

Gosling

极客大学架构师训练营

三年Java开发经验,裸辞之后筹备半年时间,四面阿里终于如愿拿到P7级offer【Java岗】。

Java成神之路

Java 程序员 架构 面试 编程语言

架构师训练营 1 期第 10 周:模块分解 - 作业

piercebn

极客大学架构师训练营

再好的技术,再完美的规章,也无法取代人自身的素质和责任心-InfoQ