系统安全——软件健壮性【转】

系统安全——软件健壮性

废话系统安全
最近一年,飞机失事的事情发生了好多起。于是乎,飞机是否是一种安全的出行工具的讨论又再一次燃起了战火。
我无意对该话题展开讨论,只是可以举个例子说明一下。
如果A城市一年出了10次抢劫事件,B城市一年出了1次杀人事件。那么可能会有很多人觉得B城市相对更不安全。
正是因为飞机失事一般会带来非常严重的后果,所以飞机的设计比其他的交通工具要优秀的多。

这里,我们参考一下传统工程的设计思想,来看看我们的系统是否安全。

先说明一下,在本文中,安全的定义比较广义,即是系统不会被灾难性的破坏。
比如:汽车自动驾驶系统不会突然指令错误,账务系统不会出现计算错误而对用户造成资金损失。
所以可以认为是一种健壮性。

从案例看起
那么,首先看一个案例——法航447号航班空难
简单介绍一下官方公布的失事原因

飞机在夜晚启用自动驾驶模式后,进入乱流区域,然后皮托管结冰。皮托管是安置在飞机外面,根据气流经过的速度而取得飞机速度的一种装置。所以皮托管结冰后,飞机无法得知当前速度,系统解除了自动驾驶模式并开始报警。驾驶员接手开始手动驾驶飞机。而突然听到报警有些紧张的驾驶员由于无法得知当前速度,所以拉升飞机。(人们只是猜测他可能是出于本能)抬升角过高,所以导致飞机失速。想象一下,飞机如果水平向前,将获得向前的动力,如果机头过高,则水平方向的速度将会降低,最终失速而往下掉。最终掉入大海。

皮托管,右边进气左边出气,根据气流测速

这个案例其实给我们一个非常深刻的教训,除了飞行员驾驶失误意外,系统设计不足也占有非常重要的原因。

1、合理的 Barrier
在设计中,Barrier是一个非常重要的考虑因素。Barrier是防止系统出错,或者说是当系统出现异常的时候的一种自我防御机制。
例如:
家庭用电时要考虑空气开关。
自动扶梯要考虑紧急制动。而不是设置一个警示牌教导人遇到情况怎么从扶梯上跳下来。
房间要考虑烟雾报警器并连接消防局。而不是安排一个人敲锣高呼天干物燥小心火烛。
汽车要安装安全带。

而本案例中,皮托管会结冰,并且结冰后无法测速这个难题在设计的时候确实有过考虑,而它的防御机制则是:系统报警。
恰巧,接手处理报警的飞行员经验不足,而最终导致失事。
当我们在设计系统的时候,需要考虑怎么设置一个良好的Barrier,尽最大可能去解决问题,而尽可能少的将问题抛给愚蠢的人类去处理。

2、必要的 Barrier
对于关键的组件,必要的 Barrier 则是为它创建一个基于完全不同实现的备用组件。假如组件A失效的可能性为1%,而备用组件B失效的可能性为2%,那么由组件A组件B组成的新组件失效的可能性就只有1%*2%为0.02%了。大大降低了故障可能发生的几率。
例如:

家里的空气开关往往是多层控制,以避免单个失效(分闸不跳总闸跳)。民航飞机往往不止一个发动机引擎,起落架不止一种控制方式,通讯方式不止一种。。。汽车在脚刹失灵的情况下,可以使用手刹。医院急救室会配置一个柴油发电机。

如图所示,如果Barrier是基于相同的算法或者实现方式,那么它们可能会有同样的漏洞,无法起到真正的防御作用。

法航失事的案列正好也说明了空客A330-203的测速装置设计不足。如果再配有另外一种不基于气流测速的装置,可能不会导致无法测速,也不会最终导致系统报警。 
所以当我们在设计关键的模块或者算法的时候,需要增加一种或者多种不同实现,进行交叉校验。以保证模块或者算法输入输出正确。


如图,模块1与模块2的结果核对相同后,才确定最终输出
3、高内聚并低耦合
曾经看到过一个案例,有位先生开着汽车出去兜风,发动机突然熄火。结果刹车和方向盘同时失灵,因为发动机熄火后没有助力提供了。
所以,我们的功能必须首先高内聚,形成一个模块一个组件,这样才能对它添加Barrier。 而模块间的联系越少,则它的Barrier更容易实现且更坚固。
前面那个刹车失灵的例子也正说明了发动机、刹车和方向盘这些部件之间的关系过于紧密而导致互相影响,一个失效而带来了连锁反应。
从程序的角度来看,可以举个例子,如果一个VO从前端经过各个功能模块最终传递到数据库,那这样无法避免模块间的互相干扰——假如变更了VO中的一个变量,则可能模块A、B、C可能同时受到影响。同时,为模块A、B、C设置的Barrier可能也无法正常工作。从测试的角度来看,这也是一种灾难。

总结:
反思我们的系统,是不是有这样的情况:

没有必要的校验或者不合理的对异常情况处理方式而出错。设计时过多考虑人工介入处理而不是灾难恢复。关键部分没有交叉校验而采用单一方法而出错,往往表现为单一方法测试不充分。改了模块A,模块B运行出状况了。看起来一系列巧合的事件同时发生。(其实是相互影响造成的,而恰恰是需要各自独立的地方)他的接口出异常了,我的系统崩溃了。
一个好的软件系统,需要代码的功能内聚,职责单一,模块间低耦合,并且需要每个重要的功能设置合理和必要的Barrier以保证输入输出正确。
因为彼此不信任,所以安全。

引用列表:
http://zh.wikipedia.org/wiki/%E7%9A%AE%E6%89%98%E7%AE%A1
--------------------- 
作者:平白 
来源:CSDN 
原文:https://blog.csdn.net/wcxiaoych/article/details/43541385 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/unsv29/article/details/83857245