)
文章目录1. 批判性分析Critical Analysis介绍1.1 什么是批判性分析 / 关键性分析1.2 为什么批判性分析很重要1.3 批判性思维和批判性分析的区别2. 批判性分析的技术与工具2.1 FMEAFailure Modes and Effects Analysis失效模式与影响分析2.1.1 步骤2.1.1.1 列出系统的组成部分或功能2.1.1.2 评估严重程度、发生概率、检测难度Assess Severity, Occurrence, Detection2.1.1.2.1 RPNRisk Priority Number风险优先级数2.1.1.2.2 收集严重程度 S 的数据2.1.1.2.3 收集发生概率 O 的数据2.1.1.2.4 收集发生概率 D 的数据2.1.2 示例 12.1.3 示例 22.1.4 练习 12.1.5 Quantitative FMEA定量 FMEA2.1.6 Mitigation Prioritization缓解措施优先级排序2.1.7 练习 22.2 RCARoot Cause Analysis根本原因分析2.2.1 五个为什么2.2.2 示例 12.2.3 示例 22.2.4 进阶 RCA2.2.4.1 故障树分析Fault Tree AnalysisFTA2.2.4.1.1 Fault Tree AnalysisFTA故障树分析 的作用2.2.4.1.2 FTAFault Tree Analysis故障树分析具体怎么工作2.2.4.1.3 识别并量化原因Identifying and Quantifying the Causes2.2.4.1.4 计算故障发生概率Calculate Failure Probabilities2.2.4.1.5 练习 12.2.4.1.6 概率数据的“动态”性质Dynamic Nature2.2.4.1.7 概率数据的“静态”性质Static Nature2.2.4.1.8 概率数据的混合性质Mixed Nature2.2.4.1.9 示例32.2.4.1.10 练习 22.3 把 RCA 和 FMEA 连接起来1. 批判性分析Critical Analysis介绍1.1 什么是批判性分析 / 关键性分析Critical Analysis 是一个系统性的评估过程用来评估软件产物的strengths优点 / 强项weaknesses缺点 / 弱点validity有效性 / 合理性Critical Analysis 在软件工程中的目的是尽早发现缺陷Identify defects early。例如在需求阶段就发现问题避免后期开发完才返工。提高系统可靠性Improve system reliability。也就是让软件更稳定、更少出错。优化开发流程Optimize development processes。例如发现某些开发步骤效率低、容易出错然后进行改进。1.2 为什么批判性分析很重要大约 60% 的软件缺陷来源于需求阶段。在软件上线后再修复 bug成本可能是在设计阶段修复的 100 倍。现实世界中的影响例子有Therac-25 事故1985–1987软件缺陷导致了致命的辐射过量事故。1.3 批判性思维和批判性分析的区别批判性思维 是一种比较通用的思考能力用来解决问题和进行逻辑推理。批判性分析 是针对某个具体对象进行有重点、有结构的评价。它们有重叠的地方都需要Logical reasoning逻辑推理Skepticism怀疑精神 / 不盲目相信二者的区别是批判性分析会使用某个专业领域里的工具和方法。2. 批判性分析的技术与工具失效模式与影响分析Failure Modes and Effects AnalysisFMEA找出系统可能会在哪里出错以及这些错误会造成什么影响Identifies potential failures and their impact。根本原因分析Root Cause AnalysisRCA把问题一步步追溯到最根本的原因Traces problems back to their origin。SWOT 分析SWOT Analysis从四个方面优势、劣势、机会、威胁分析一个系统、项目或方案Evaluates strengths, weaknesses, opportunities, threats。代码审查Code review系统地检查源代码Systematic examination of source code。需求验证Requirements Validation确保需求是清楚的、完整的、可以测试的Ensures requirements are clear, complete, and testable。这些分析方法不只是“最佳做法”而且经常是法律或行业标准要求必须做的。例如医疗软件 需要遵循 ISO 14971 标准。汽车软件 需要遵循 ISO 26262 标准。2.1 FMEAFailure Modes and Effects Analysis失效模式与影响分析FMEA 是主动预防型的它是一种计划工具用来在麻烦发生之前就阻止它。FMEA 会列出系统中所有可能的故障然后对它们进行评分最后决定哪些问题要优先修复。这里的评估标准有缩写英文中文含义SSeverity严重程度问题发生后有多严重OOccurrence发生概率这个问题有多可能发生DDetection检测难度这个问题在发生前有多容易被发现一般来说S 越高说明后果越严重O 越高说明越容易发生D 越高说明越难提前发现。然后通常会计算一个风险优先级RPN S × O × DRPN 越高说明这个问题越应该优先处理。假设我们正在开发一个 网上商店系统。我们提前预测到支付系统可能会失败比如信用卡无法处理付款。然后我们按照 S、O、D 标准评估该问题的严重程度、发生概率和检测难度并计算 RPN。根据 RPN 的高低我们判断该失效模式的优先级。如果 RPN 较高就需要优先添加相应的预防措施、缓解措施或备用方案例如备用支付方式、失败重试、异常监控和防止重复扣款机制。2.1.1 步骤列出系统的组成部分或功能List components/functions of the system。识别潜在的失效模式也就是找出每个部分可能会怎么出错Identify potential failure modes。评估三个指标并计算风险优先级数 RPNAssess severity, occurrence, detection (Risk Priority Number: RPN)。缩写英文中文含义SSeverity严重程度这个故障发生后有多严重OOccurrence发生概率这个故障有多可能发生DDetection检测难度这个故障有多难被提前发现2.1.1.1 列出系统的组成部分或功能我们应该把系统中的哪些功能纳入 FMEA 分析我们可以根据评估风险 SOD 去回答这个问题。SOD 在这一步上那就是如果这个功能失败后果很严重Failures have high impactSeverity, S。这个功能比较容易出错发生概率较高Failures are likelyOccurrence, O。这个功能出错以后不容易被提前发现Failures are hard to catchDetection, D。所以在做 FMEA 时应该优先选择那些“出错后影响严重、发生概率较高、又不容易被发现”的系统功能进行分析。、具体的步骤如下理解系统的目的和范围Understand the System’s Purpose and Scope评估关键性和影响Assess Criticality and Impact评估使用频率和暴露程度Evaluate Usage and Exposure检查复杂性和变更频率Check Complexity and Change Frequency评估检测难度Assess Detection Challenges利用历史故障记录Leverage Historical Failures考虑外部接口Consider External Interfaces2.1.1.2 评估严重程度、发生概率、检测难度Assess Severity, Occurrence, Detection这里我们再看一下SOD分别是什么意思SeverityS严重程度如果这个故障发生了它对系统、用户或业务的影响有多严重评分一般是 1minor 到 10catastrophic。OccurrenceO发生概率这个故障发生得有多频繁评分也是 1rare 到 10frequent。DetectionD检测难度在问题影响用户之前我们有多大可能提前发现它评分也是 1always detected 到 10undetectable。2.1.1.2.1 RPNRisk Priority Number风险优先级数RPN Severity × Occurrence × Detection风险优先级数 严重程度 × 发生概率 × 检测难度也就是RPN S × O × DRPN 高的问题需要立即关注。但是批判性分析要求任何 Severity 为 9 或 10 的项目不管总 RPN 是多少都必须被处理因为它对人的生命或整个系统完整性的风险太高不能忽视。2.1.1.2.2 收集严重程度 S 的数据也就是说不能随便给 S 打分可以以下面的几种方法来收集数据。用户影响分析User Impact Analysis数据来源User stories用户故事Requirements docs需求文档Customer support tickets客户支持工单 / 客服反馈记录方法检查这个故障会怎样影响用户。利益相关者意见Stakeholder Input数据来源Product managers产品经理Developers开发人员Business analysts业务分析师方法可以开一个讨论会或者做问卷调查让相关人员根据业务目标给影响程度打 1 到 10 分。行业标准Industry Standards数据来源我们可以参考行业里的 FMEA 指南或软件风险管理标准。例如AIAG汽车行业常用的 FMEA 指南IEC 60812关于 FMEA 方法的国际标准ISO 27001信息安全管理标准常用于软件安全风险分析。方法使用预先定义好的严重程度评分表predefined severity tables。历史数据Historical Data数据来源可以参考过去系统中真实发生过的问题记录比如Incident reports事故报告Post-mortems事后复盘报告Bug trackers缺陷跟踪系统比如 Jira方法分析过去故障造成过什么影响。2.1.1.2.3 收集发生概率 O 的数据在 FMEA 里评估一个故障“有多容易发生”时不能完全凭感觉要参考多方面。日志分析Log Analysis数据来源System logs系统日志Error tracking错误追踪工具比如 Sentry、New Relic方法统计一段时间内故障发生的次数。测试数据Testing Data数据来源Unit test results单元测试结果Integration test results集成测试结果Load test results负载测试结果 / 压力测试结果方法运行测试来模拟不同条件下系统是否会出错。开发人员估计Developer Estimates数据来源Software engineers软件工程师Architects系统架构师方法根据代码复杂度和过去的 bug 记录讨论并估计故障发生概率。使用模式 / 使用规律Usage Patterns数据来源数据分析工具Analytics例如Google Analytics、server metrics通过数据分析工具或服务器指标来观察用户怎么使用系统。方法把故障和用户活动情况联系起来分析。基准数据 / 行业参考数据Benchmarks数据来源行业数据或者供应商服务等级协议vender SLA例如 AWS uptime stats方法使用典型故障率来估计问题发生概率例如网络中断平均每小时 0.01 次。2.1.1.2.4 收集发生概率 D 的数据我们可以从多个方面判断一个故障是否容易被发现。测试覆盖率Test Coverage数据来源Test reports例如 JaCoCo、pytest 这些测试工具生成的报告。方法测量有多少比例的代码被测试到了。监控系统Monitoring Systems数据来源Logs, alerts例如 Prometheus、Datadog。方法检查故障发生时系统是否会触发报警。质量保证流程QA Processes数据来源Development lifecycle例如代码审查、静态分析。意思是是说看开发流程中有没有质量检查环节。方法评估这些控制措施是否足够强。用户报告 / 用户反馈User Reports数据来源Support tickets客服工单Bug reportsBug 报告 / 缺陷报告方法如果是用户先发现问题而不是系统提前发现那么 Detection 分数就高。设计审查Design Reviews数据来源Architecture docs架构文档Peer reviews同行评审 / 同事评审可以通过检查系统架构文档、让其他工程师评审设计判断系统有没有内置的检查机制。方法评估系统中是否有内置检查机制。2.1.2 示例 1我们用几个例子来说明 FMEA。示例1是游戏 App。需求层面的 FMEA功能 / 需求游戏要能在所有手机上运行。失效模式游戏在旧手机上卡顿。RPN 评分严重程度S 8如果游戏很卡玩家可能会直接退出游戏。发生概率O 4因为市场上还有不少用户在用旧手机所以这个问题有一定可能发生。但不是所有用户都会遇到所以不是特别高。检测难度D 3因为这个问题比较容易测试。开发团队可以拿一些旧手机测试游戏运行情况很容易发现卡不卡。所以RPN 8 × 4 × 3 96解决方案优化图形。2.1.3 示例 2这里分析一个银行 APP。从系统设计角度分析 FMEA功能把钱转到另一个账户。失效模式如果服务器宕机转账可能失败。RPN 评分严重程度S 10因为银行转账涉及用户的钱。如果转账失败导致钱丢失、扣款异常、账户金额错误这就是非常严重的问题。发生概率O 2服务器宕机不是每天都会发生所以发生概率较低。检测难度D 5比如服务器突然宕机可能只有在转账请求发送时才发现。如果没有良好的监控、重试机制和状态检查就可能比较难及时发现和处理。所以RPN 10 × 2 × 5 100解决方案添加离线队列offline queue。当服务器暂时不可用时系统不要直接让转账请求丢失而是先把请求安全地排队保存起来等服务器恢复后再继续处理。2.1.4 练习 1我们尝试通过一个练习更加全方位的使用 FMEA。任务对一个在线投票系统进行 FMEA 分析。需要分析的功能用户身份验证投票提交结果统计我们的步骤还是识别 3 个失效模式。或者说是找出 3 个可能出错的情况。给每个故障打 S、O、D 分数。计算RPN。结果如下用户认证 / 身份验证的失效模式是密码泄露。评分是Severity 10非常严重因为会影响投票合法性和用户安全Occurrence 3发生概率不是特别高Detection 4有一定可能发现但不一定很容易RPN 10 × 3 × 4 120。投票提交的失效模式是重复投票。评分是Severity 8比较严重因为会影响投票公平性Occurrence 2发生概率较低Detection 5检测难度中等RPN 8 × 2 × 5 80。结果统计 / 计票的失效模式是计票错误。评分是Severity 10非常严重因为会直接影响最终投票结果Occurrence 1发生概率很低Detection 3相对容易检测RPN 10 × 1 × 3 30。2.1.5 Quantitative FMEA定量 FMEA传统 FMEA 里S、O、D 通常是人工打分范围是 1 到 10。这种打法有一定主观性因为分数主要靠经验判断。进阶方法进阶 FMEA 会尽量用真实数据来代替主观打分。严重程度S可以用具体指标来衡量比如系统停机时间百分比、收入损失。发生概率O可以用历史数据或 MTTF 来判断比如MTTFMean Time To Failure平均无故障时间。检测能力D可以用测试覆盖率或检测概率来表示。比如测试覆盖率 80%这就相当于原来传统 FMEA 的 2 分。因此传统 FMEA 里D 越高 越难发现 风险越大。现在在 D 表示检测概率detection probability因此D% 越高 越容易发现 风险越低。所以现在 RPN 的计算公式为 RPN S × O × (1 - D%)RPN 严重程度 × 发生概率 ×1 - 检测概率2.1.6 Mitigation Prioritization缓解措施优先级排序做完 FMEA 后我们不仅要知道哪些风险高还要决定先解决哪个问题最划算、最值得投入资源。我们使用成本—收益模型Cost-Benefit Model解决这个问题。成本—收益模型Cost-Benefit Model用两个方面来判断Cost Development effort (hours) Tooling cost也就是说修复成本包括花费的时间以及所花费的成本。比如修复一个数据库崩溃问题需要工程师工作 50 小时成本大约是 5000 美元。Benefit Risk reduction (ΔRPN × Impact)意思是说收益来自于风险降低了多少。比如修复这个数据库崩溃问题可以将 RPN 从 200 降低到 50并减少 10K 美元损失那么这里的收益就是 200 - 50× 10,000 1,500,000 美元所以就是投资回报率ROIReturn on Investment高。2.1.7 练习 2我们通过一个练习尝试使用定量 RPN 的 FMEA。练习要求我们分析一个云存储 API。失效模式高负载情况下上传失败。MTTFMean Time To Failure平均无故障时间 1000 hDowntime $5K/h意思是系统停机或上传功能不可用时每小时损失 5000 美元。Test Coverage 90%。因此指标计算如下严重程度S$5K/hour × 1-hour outage $5K impact → 8因为上传失败停机 1 小时每小时损失 5000 美元这个损失比较高但还没有达到灾难级别。发生概率OMTTF 1000 hours → Failure rate 1/1000 0.001/hour → 2MTTF 1000 h所以 1 / 1000 0.001 次/小时这个发生概率比较低所以给 2。检测能力D:90% coverage → D% 0.9 → (1 - 0.9) 0.1 → 1这个计算用具体的公式参考较为简单。我们现在计算 RPN 8 × 2 × 1 16。缓解措施增加自动扩容机制用来应对流量高峰。2.2 RCARoot Cause Analysis根本原因分析RCA 是反应型的reactive它像侦探工具一样用来在问题发生之后找出原因并修复问题。例子网上商店上线后支付系统崩溃了。我们开始问“为什么”最后发现原因是服务器无法承受 1000 个用户同时访问因为之前没有做负载测试。2.2.1 五个为什么对于 RCA我们的常用方法是 五个为什么5 Whys。遇到问题后不只停留在表面原因而是连续追问“为什么”直到找到根本原因。不一定真的必须问满 5 次重点是要一直追问到真正原因。例如我们前面问题是系统在高峰负载时崩溃。然后开始追问为什么系统崩溃Why? → Server overload因为服务器过载了。继续追问为什么服务器会过载Why? → Insufficient scaling.因为扩展能力不够。接着追问为什么扩展能力不够的问题之前没发现Why? → No load testing.因为没有做负载测试。2.2.2 示例 1我们再看几个示例。第一个例子是有关一个太空射击游戏崩溃的问题。我们尝试用五个为什么去进行 RCA。为什么因为敌人生成得太快。为什么敌人生成太快因为循环没有限制。根本原因缺少敌人生成速率上限。解决方法添加限制。2.2.3 示例 2我们再看一个银行 APP 的例子。问题转账重复。为什么因为重新点击转账按钮重新发送了请求。为什么重试会导致重复转账因为系统没有检查唯一 ID。根本原因缺少交易 ID。也就是说系统没有给每笔转账设置唯一的交易编号所以无法判断两次请求是不是同一笔交易。解决方法添加 ID。这样即使用户点击重试系统也能识别这是同一笔转账请求不应该重复执行。2.2.4 进阶 RCA基础 RCA 通过 5 Whys 方法挖掘问题的根本原因。进阶 RCA 通过 故障树分析Fault Tree AnalysisFTA。FTA Fault Tree Analysis故障树分析用逻辑树和概率来分析故障原因。FTA 会把一个最终故障放在最上面比如系统崩溃然后往下分解可能原因服务器过载数据库故障网络中断代码死循环第三方服务失败。每个原因还可以继续往下分解并且可以给它们加上发生概率。这样就能判断哪个原因最可能导致系统故障。FTA 还可以用贝叶斯推断Bayesian Inference来分析。贝叶斯推断Bayesian Inference用统计方法不断修正refine我们对原因的判断guesses。2.2.4.1 故障树分析Fault Tree AnalysisFTA故障树分析Fault Tree AnalysisFTA是进阶 RCA 里的一种方法用来系统地分析某个故障是由哪些原因造成的。FTA 是一种自上而下的top-down、演绎式deductive的分析方法用来识别和分析某个具体系统故障的原因。自上而下top-down是因为先从最上面的故障开始然后一步步往下找原因。演绎式deductive是从一个已知的问题出发推导出可能导致它的原因。顶事件放在故障树最上面下面的分支就是导致这个故障的各种可能原因、子原因和条件。因此 FTA 是可视化的、逻辑化的、系统化的visual, logical, and systematic。2.2.4.1.1 Fault Tree AnalysisFTA故障树分析 的作用FTA 的目的如下识别系统薄弱点Identifying Weak Points通过可视化地展示单个组件的故障如何在系统中传播FTA 可以帮助工程师找到“单点故障”。定量可靠性评估Quantitative Reliability AssessmentFTA 可以帮助计算顶事件发生的概率。确定安全与资源投入的优先级Prioritizing Safety and ResourcesFTA 可以帮助我们判断资源应该投到哪里。诊断和故障排查Diagnostic Troubleshooting当故障真的发生以后可以用故障树来检查各个组件的状态从而定位问题。总结一下就是 FTA 的作用是帮助我们找出系统薄弱点计算故障发生概率决定资源优先投入在哪里并在故障发生后帮助排查原因。2.2.4.1.2 FTAFault Tree Analysis故障树分析具体怎么工作FTA 的具体步骤如下定义顶事件Define the Top Event识别原因Identify Causes使用逻辑门Use Logic Gates继续向下拆分原因Break Down Further量化Quantify分析Analyze前面提到的逻辑门包括两种逻辑门意思OR gate只要其中一个原因发生顶事件就可能发生AND gate必须多个原因同时发生顶事件才会发生事件也可以进行划分顶事件Top event故障树最上面的事件也就是我们最终要分析的主要故障。中间事件Intermediate event中间事件是顶事件下面的原因但它本身还可以继续被分解。基本事件Basic event基本事件是最底层、不能再继续分解的具体原因。未展开事件Undeveloped event这是一个暂时不继续分析的事件。下图给出了一个例子。2.2.4.1.3 识别并量化原因Identifying and Quantifying the Causes在做故障树分析时我们要找出哪些组件故障、系统问题或操作问题可能导致 Top Event顶事件。设计工程师 / 系统工程师可以从系统结构角度找原因运维和维护团队可以从真实运行情况、日志和故障现场中提供证据帮助我们判断哪些原因可能导致顶事件。设计工程师 / 系统工程师Design / Systems Engineers他们负责识别硬件或软件组件之间是如何交互的并判断哪些组件故障可能导致顶事件。运维和维护团队Operations Maintenance Teams他们是问题发生后最先响应的人。运维团队可以告诉我们系统实际运行时是什么样的ground truth真实情况而不只是设计文档里写的样子。到这里我们成功识别了原因Identifying the causes。我们现在开始量化原因Quantifying the causes。可靠性工程师Reliability Engineers可靠性工程师会使用历史数据、制造商规格说明以及 MTBF 来给基本事件分配具体数值。安全 / 风险管理部门Safety / Risk ManagementHSE在高风险行业比如石油天然气或航空业这些部门负责确保量化后的风险符合监管标准。数据科学家Data Scientists在现代软件环境中数据分析人员可以通过日志、遥测数据和大量用户会话中的错误率来量化原因。2.2.4.1.4 计算故障发生概率Calculate Failure Probabilities我们现在通过一个例子来看一下怎么计算故障发生概率Calculate Failure Probabilities。我们先提供几个底层原因的发生概率事件中文意思概率/故障率Server offline服务器离线0.01/hourAuth failed认证失败0.02/hourToo many transactions交易太多0.05/hourNo lock timeout没有锁超时机制0.1No validation没有输入验证0.03那么现在支付网关失败的概率是多少呢支付网关失败的可能有两种服务器离线 或 认证失败。因此这里是一个 OR gate或门。因此如果 A 和 B 是两个独立事件A Server offlineB Auth failed那么p(A OR B) 1 - p(A 不发生 AND B 不发生)也就是p(A OR B) 1 - (1 - p(A)) × (1 - p(B))代入数字p(Server offline) 0.01p(Auth failed) 0.02p(Payment Gateway failed) 1 - [(1 - 0.01) × (1 - 0.02)] 1 - 0.99 × 0.98 1 - 0.9702 0.0298/hour那么我们现在要计算数据库锁死的概率怎么计算呢数据库锁死 交易太多 AND 没有锁超时机制这里是 AND gate与门表示两个条件要同时发生才会导致数据库锁死。所以计算方法是p(DB locks) p(Too many transactions) × p(No lock timeout)代入数字p(Too many transactions) 0.05/hourp(No lock timeout) 0.1p(DB locks) 0.05 × 0.1 0.005/hour计算输入崩溃的概率输入崩溃 没有输入验证 OR 某个未展开事件但是这个 undeveloped event未展开事件 没有给具体概率。因此p(Input crash) 0.03计算结账失败的概率它由三个中间事件导致就是我们刚刚计算的三个支付网关失败、数据库锁死、输入崩溃.这三个之间是 OR gate或门。只要其中任何一个发生都可能导致结账失败。所以公式是p(Checkout fails) 1 - (1 - 0.0298) × (1 - 0.005) × (1 - 0.03) 1 - 0.9702 × 0.995 × 0.97 1 - 0.9364 0.0636/hour这里或许有人会有问题为什么计算 OR gate或门的时候是 1 减去两者都不发生的概率而不是直接将这里 事件 A 和 事件 B 的概率相加。因为对于两个独立事件有四种情况事件 A 和 事件 B 都发生事件 A 发生 但事件 B 不发生 事件 B 发售 但事件 A 不发生 事件 A 和 B 都不发生。OR gate或门是只要有一个发生那么上层事件就会发生所以这里包含前三种情况。那么如果我们直接将 事件 A 和 事件 B 的概率相加这里 事件 A 发生的概率包含事件 A 和 事件 B 都发生事件 A 发生 但事件 B 不发生两种情况的概率。事件 B 发生的概率包含事件 A 和 事件 B 都发生事件 B 发生 但事件 A 不发生两种情况的概率。所以这里两种情况都发生的概率算了两次所以不能在这个例子中直接 0.01 0.02。计算“至少一个事件发生”的概率的步骤是先算两个事件都不发生的概率。用 1 减去这个结果。也就是上面计算的过程。2.2.4.1.5 练习 1我们现在尝试一个场景用户无法登录银行 App。现在我们建立一个 fault tree故障树然后计算登录失败的概率。顶事件Login fails登录失败它可能由两个原因导致DB down数据库宕机、Auth error认证错误。只要数据库宕机或者认证错误用户就可能登录失败。这是 OR gate或门。数据库宕机可能由两个原因导致Power outage停电概率是 0.01/hourDB crash数据库崩溃概率是 0.02/hour。这里也是 OR gate或门。认证错误需要两个条件同时发生Bad credentials用户凭证错误比如用户名或密码错误概率 0.04/hourNo retry没有重试机制概率 0.5。这里是 AND gate与门。我们先计算 DB down数据库宕机的概率p(DB down) 1 - (1 - 0.01) × (1 - 0.02) 1 - 0.99 × 0.98 1 - 0.9702 0.0298/hour再计算Auth error认证错误的概率p(Auth error) 0.04 × 0.5 0.02/hour最后计算登录失败的概率p(Login fails) 1 - (1 - 0.0298) × (1 - 0.02) 1 - 0.9702 × 0.98 1 - 0.950796 0.049204/hour2.2.4.1.6 概率数据的“动态”性质Dynamic Nature故障树里有些事件的概率是 随时间发生的故障率比如“每小时发生多少次”有些事件则是 没有时间单位的条件概率或状态概率。所以前者这些是 动态事件会随着时间发生所以用 每小时 来表示故障率。后者这些事件是 静态条件不是按小时发生的。Dynamic动态指的是这些事件会随着时间随机发生不是一直固定存在的状态。如果一个概率写成 “每小时多少”比如 0.01/hour它表示的是故障率failure rates。故障率failure rates指的是某个故障在一段时间内发生得有多频繁。故障率被用于动态事件那些随机发生或间歇发生的事件。基于时间分析的系统当我们分析系统在一段时间内的行为时就会用这种动态概率。在故障树分析中故障率failure rate通常和 MTTFMean Time To Failure平均无故障时间有关系。例如网关服务器离线的故障率是0.01/hour那它的 MTTF 就是MTTF 1 / 故障率 1 / 0.01 100 hours在软件系统中每小时故障率 通常来自三类数据。Logs日志可以通过历史日志来统计故障率。比如服务器在 500 小时内崩溃了 5 次。那么故障率就是5 / 500 0.01/hour。Metrics监控指标可以通过监控系统的数据计算故障或异常发生率。比如在 1000 小时内发生了 50 次流量高峰。那么发生率就是50 / 1000 0.05/hour也就是说平均每小时发生 0.05 次流量高峰。Vendor Specs供应商规格说明也可以参考供应商提供的可靠性数据比如服务器、云服务、数据库服务的可用性说明。例如服务商承诺 99.9% uptime系统正常运行时间比例。所以可以近似理解为downtime rate 0.0012.2.4.1.7 概率数据的“静态”性质Static Nature概率的静态性质Static Nature指的是这个问题不是随着时间随机发生的而是系统设计或配置中本来就存在的状态。没有时间单位的概率是静态概率。它们不是故障率而是一次性的、没有单位的概率。适用于Constant Conditions固定条件 / 常态条件有些问题不是运行过程中突然发生的而是系统本身就存在的缺陷比如Design flaws设计缺陷Configuration errors配置错误Missing features缺少某个功能。State-Based Events状态型事件静态概率表示某个状态在某一时刻是否成立的可能性而不是它发生得有多频繁。比如No lock timeout 0.1意思不是“没有锁超时每小时发生 0.1 次”而是在当前系统设计中存在“没有设置锁超时”这个问题的可能性是 0.1。No validation 0.03意思是“没有输入验证”这个问题存在的概率是 3%。这些静态概率 通常来自三个方面Code Reviews代码审查通过代码审查发现大约 3% 的代码提交缺少输入验证。Design Audits设计审计 / 设计检查通过设计检查或配置审计发现大约 10% 的配置缺少超时设置。Assumption假设 / 粗略估计如果没有足够的数据就只能根据经验做一个粗略估计。2.2.4.1.8 概率数据的混合性质Mixed Nature我们前面计算的时候使用的是p(Checkout fails) 1 - (1 - 0.0298) × (1 - 0.005) × (1 - 0.03)这里默认了所有概率是 同一种类型、可以直接比较和组合的概率。如果我们细看这里 0.0298 和 0.005 是基于时间的概率 / 故障率。而 0.03 是静态概率。2.2.4.1.9 示例3我们现在用一个 视频流媒体 App 卡住/冻结 的例子来说明 动态概率 和 静态概率 混合出现时该怎么理解。这里的顶事件是视频播放冻结 / 卡住。下面的原因可能是网络断开、视频编解码器过时。网络断开是一个基于时间的动态故障率。过时的视频编解码器是一个非时间型概率。我们有两种方式解决这里的混合问题。把静态概率转换成时间型概率。如果有 10% 的系统实例使用了过时的 codec并且假设在高负载下这个过时 codec 有一定概率导致播放冻结。我们作出假设每小时有 10% 的概率因为 codec 解码失败而导致视频卡住。那么现在两个原因都变成时间型概率Network disconnected 0.02/hourOutdated codec 0.1/hour顶事件是视频播放卡住。它们之间是 OR gate。所以公式是p(Video playback freeze) 1 - [(1 - 0.02) × (1 - 0.1)] 1 - (0.98 × 0.9) 1 - 0.882 0.118/hour我们可以用 MTTF 表示那就是 MTTF 1 / 故障率 1 / 0.118 ≈ 8.47 小时。把静态概率当作条件概率来处理。不要强行把静态概率改成 /hour 的故障率而是把它看成一个前提条件。前一种方法把“10% 的概率使用过时 codec”理解成每小时有 10% 的概率因为 codec 过时导致视频冻结。这样做其实有点不严谨。0.1 表示系统存在过时 codec 的概率是 10%。只有当它和某个触发事件同时出现时才会导致播放冻结。比如系统有过时 codec用户刚好播放了不兼容的视频流。因此这里不要把静态概率强行改成每小时概率而是把它看成一个条件。这个条件需要和某个触发事件同时发生才会导致故障。我们把它拆成两个条件Incompatible Stream 0.05/hour 和 Outdated Codec 0.1。所以计算这里的 p(Codec fails) 0.5 × 0.2 0.1/hourVideo Playback Freeze 的概率p(Video playback freeze) 1 - (1 - 0.02) × (1 - 0.1) 1 - 0.98 × 0.9 1 - 0.9702 0.0298/hour约等于0.03/hour那么 MTTF 1 / 0.03 33.3 hours所以包括我们前面举例的 Checkout Failure结账失败的故障树计算。我们计算的是p(Checkout fails) 1 - (1 - 0.0298) × (1 - 0.005) × (1 - 0.03) 0.0636/hour因为 malicious attack恶意攻击 是一个 undeveloped event未展开事件为了简化计算暂时不考虑它。我们现在把 No validation没有输入验证 这个静态概率当作 条件概率 来处理。更严谨的计算应该是p(Input crash) p(No validation) × p(Bad input occurs)如果假设p(No validation) 0.03p(Bad input occurs) x/hour那么p(Input crash) 0.03 × x然后新的结账失败概率是p(Checkout fails) 1 - (1 - 0.0298) × (1 - 0.005) × [1 - (0.03 × x)]2.2.4.1.10 练习 2我们现在分析一个实时聊天 App最上层故障事件是用户意外断开连接。原因有网络掉线0.03/hour服务器崩溃由两个因素组成服务器过载每小时概率 0.04没有重试机制概率 0.2。这里是 AND gate。客户端 Bug有两个因素组成客户端代码 bug每小时概率 0.02用户没有更新客户端概率 0.1。这里是 OR gate。因此我们计算概率的话如果使用方法一那么计算如下p(Server Crash) 0.04 × 0.2 0.008/hourp(Client Bug)1−(1−0.02)(1−0.1)1−(0.98)(0.9)1−0.8820.118/hour那么p(User Disconnects)1−(1−0.03)(1−0.008)(1−0.118)1−(0.97)(0.992)(0.882)1−0.848695680.15130432/hour也就是用户意外断连概率约为 0.1513/hour即每小时约 15.13%。MTTF≈6.61 hours平均大约每 6.61 小时 会发生一次用户意外断连。2.3 把 RCA 和 FMEA 连接起来把 RCA 和 FMEA 连接起来就是把一次“事后得到的教训”转化成“以后提前预防的措施”。RCA 是 reactive问题发生之后分析为什么出问题FMEA 是 proactive问题发生之前提前预测风险并预防。RCA 可以发现原来不知道的风险。比如系统上线后才发现一个问题数据库发生死锁系统崩溃了。这个问题可能之前 FMEA 没有预测到。RCA 的输出是一个具体的、真实发生过的原因。把 RCA 的发现更新到 FMEA 文档里。RCA 做完之后不是写个报告就结束而是要把发现的问题加入 FMEA 表格。这样以后做系统设计、测试和上线检查时就会提前考虑这个风险。简单总结一下那就是RCA 是事后找原因FMEA 是事前防风险。把 RCA 和 FMEA 连接起来就是把真实事故中发现的根本原因补充进 FMEA 表格让以后类似问题可以被提前识别和预防。