这世界几乎不存在完全正确的软件系统,目前的趋势是:系统规模越来越大,逻辑越来越复杂,要求越来越高。这种情况下追求完全正确会让成本变得不可控。理论上,设计、实现、环境都正确的软件可以做到完全正确;现实是,这三条一条都做不到。一,就算是小型商业软件,无论测试还是形式化证明,工作量都是巨大无比,所以只能妥协而采取近似解。二,开发工具、第三方库不会完全正确,或多或少的存在缺陷。三,运行环境不一定和设计环境相同,比如:操作系统、数据库系统版本号不一致,操作系统、数据库系统本身的缺陷等。
出于对现实的妥协,容错技术应运而生,讲的是如何尽早发现缺陷,并消除或减少不利影响。容错技术可以在不同的级别实现,比如:系统级、设备级(电脑、手机)、组件级、模块级、代码级等。容错的技术的关键是冗余,消耗更多的资源以增强可靠性。资源包括三种:时间、信息(数据)、结构(组件)。
时间容错,代码级容错,执行诊断系统排除瞬时故障。目的:排除随机干扰。信息容错,代码级容错,在数据中增加一部分正常系统不需要的数据,以提前发现错误,主要消除重要数据通信的外在故障、人为篡改。结构容错,系统级、组件级容错,利用相异设计(不同的开发者、不同的开发语言)完成同一功能。
-
-
-
-
-
- 信息容错
-
-
-
-
信息偏差发生的时机主要在:一,数据传输过程中。二,数据存储过程中。三,数据运算过程中。常见的信息容错有如下三种:
-
-
-
-
-
-
- 冗余码、校验码。
-
-
-
-
-
身份证号码的最后一位就是校验码,如果输错一位,100%能发现。
-
-
-
-
-
-
-
- 奇校验码
-
-
-
-
-
-
奇校验码在原始的二进制数据最后(或最前)加上二进制1或二进制0,使得二进制1的位数为奇数。偶验证类似。都可以发现错1位、3位、5位...错误,都无法发现错2位、4位、6位...错误。绝大部分情况下是错1位。
-
-
-
-
-
-
-
- 海明码
-
-
-
-
-
-
当只有1位错误时,海明码可以定位错误位,并修正。修正方法:错误位1改成0,0改成1。下面以8位原始数据为例来说明原理。绿色表示正常,红色表示异常。
错误位 | 总校验码 | 验证码一 | 验证码二 | 验证码三 |
无错 | ||||
第0位 | ||||
第1位 | ||||
第2位 | ||||
第3位 | ||||
第4位 | ||||
第5位 | ||||
第6位 | ||||
第7位 |
绿色为1,红色为0,4个校验码各一个二进制位。
下表表示4位原始码错2位,4位原始数据需要3位验证码,下表只考虑错两位的情况,且不考虑总验证码。
错误的两位 | 验证码一 | 验证码二 |
0,1 | ||
0,2 | ||
0,3 | ||
1,2 | ||
1,3 | ||
2,3 |
上表结论:
- 如果错两位,无论如何都无法纠正。
- 如果错两位,可以发现错误。
海明码总结:
- 总验证位验证所有位。
- 各分验证位验证一半的位。
-
-
-
-
-
- 多处存储
-
-
-
-
-
将重要数据保存多处,以避免偶然性故障(比如:断电)。访问时,先判断是否一致,如果一致就读取,否则就转入异常处理。
-
-
-
-
-
-
- 日志和备份
-
-
-
-
-
理论上:只新增,不修改、不删除的系统永远不会出错。比如银行只记录存款、取款、转账操作,不修改账号余额,就不会出错。但这样存储开销太大,运行性能太低。折中一下,每天04:00统一修改一次余额,其它时间在此的基础上统计余额。每天的余额就是备份,每天的操作记录就是日志。有了备份和日志,可以在严重操作失误、硬盘损坏、天灾人祸、病毒破坏的情况下,快速恢复系统。
-
-
-
-
-
- 时间容错
-
-
-
-
失败后,重做。类似通过减法验算加法。包括:指令复执、程序卷回,两者的本质是相同的,前者从程序员的角度来看问题,后者从概要设计师的角度看问题。指令复执,指的是重复执行语句。比如:轮询,每10毫秒查询客户端是否有数据发过来。程序卷回,指的是某串行功能设置若干个恢复点,发现异常时,程序回到前一个恢复点继续执行。某CDC软件开发商,为了增加稳定性,将从相机取图和图像检测分成两个exe,取图exe启动一个实例,检测exe启动3到5个实例。这样一个检测exe崩溃后,其它检测exe可以继续运行。检测exe崩溃的几率大约100万分之一,检测100万帧大约需要10天。如果超时(在指定时间没有收到结果),则重新发送请求。无论运行了多少检测exe,每个请求只会执行一次。如果因为超时重发而收到两个结果,以先收到的结果为准。
-
-
-
-
-
- 结构容错
-
-
-
-
本部分包括三部分:一,结构容错的核心:相异性设计。二,两种结构容错。三,两种结构容错的优缺点。
-
-
-
-
-
-
- 相异性设计
-
-
-
-
-
- 由不同的人员完成。包括但不限于:分析、设计、实现、测试人员。
- 不同的思想。比如:面向对象、面向过程,不同的架构模式、设计模式。
- 不同的开发语言,如:C++、C#、JAVA。
- 不同的开发环境,VS、QT;不同的框架、类库。
- 不同的算法,比如:图像平移,可以直接加减法,也可以用矩阵实现仿射变换。
- 不同的运行环境,比如;操作系统、数据库软件。
-
-
-
-
-
- N版程序
-
-
-
-
-
对于同一功能,N(N>2)个开发团队开发N个可运行的程序,在不同的机器上运行。最终结果由这N个程序的结果综合得到。表决方式可以是多数表决或一致表决。结果很可能有误差,所以表决的时候,要考虑误差。表决的时候不一定等权,某些程序可能权重更高。结果不一定正确,可能异常,要做好异常处理。N版程序的改进版,只对某个模块进行N版设计。
-
-
-
-
-
-
- 恢复块
-
-
-
-
-
通俗的说,恢复块不但有正常的模块,还有一到多个备用模块。正常模块运行失败、异常、结果异常时,运行备用模块。难点:环境的恢复。有两个方法:一,运行前备份环境,运行前利用备份恢复环境。二,通过逆运算恢复环境。前者实现简单,后者性能好。备用模块的来源:一,专门设计的。二,淘汰下来的旧模块。三,重新设计、实现的低要求模块,比如:降低性能要求、降低精度要求。
-
-
-
-
-
-
- N版程序、恢复块优缺点
-
-
-
-
-
N版程序设计的优点:简单可行,多进程(多线程)加速。
恢复块优点:无需增加硬件,支持细粒度。
N版程序设计缺点:
- 工作量增加了几倍。
- 通信麻烦,局域网、跨进程、跨线程。
- 要处理复杂的同步、异常。
恢复块缺点:
- 运行时间不确定、不稳定。运行多个备用块,显然用时较多,可能引起网络、数据库超时。
- 环境复杂的时候,备份工作会大幅增加开发工作量和内存(甚至硬盘)消耗。
- 验证测试困难。理论上要需要知道所有错误的可能,而这往往不可能。