20、软件未来-proofing:应对技术挑战的策略

软件未来-proofing:应对技术挑战的策略

在软件开发和系统维护的过程中,我们常常会面临各种意想不到的问题。这些问题可能源于时间计算的误差、硬件设备的故障,或者是自动化系统的失效。为了确保软件系统的稳定性和可靠性,我们需要采取一系列的策略来应对这些挑战。

1. 预见并应对软件问题

在软件开发过程中,我们应该花时间考虑软件如何处理一些极端情况,例如日期偏差 20 年、时间倒流一秒、出现技术上不可能的数字(如晚上 11:59:60),或者存储驱动器突然消失等问题。当遇到不确定的情况时,默认采取谨慎的态度是很重要的,因为及时发现错误才能解决问题。

2. 缩短升级间隔

以 2019 年的两个重要时间漏洞为例,我们可以看到升级间隔对系统稳定性的影响。
- GPS 周数溢出 :GPS 用 10 字节的存储块表示周数,最多能存储 1024 个值,相当于 19.7 年。当达到第 1025 周时,会重置为零,可能导致计算机将所有时间回溯 20 年。1999 年第一次发生时,由于 GPS 还不普及,影响较小。但到 2019 年,几乎所有手机都配备了 GPS 芯片,并且有大量应用基于 GPS 构建。不过,由于人们经常更换支持 GPS 的设备,手机应用更新无缝且自动,所以 2019 年的溢出事件基本没有造成大的影响。
- 闰秒问题 :闰秒是为了使计算机时钟与太阳周期同步而额外增加的一秒。闰秒不像闰年那样可以预测,因为地球的自转速度在不断变化,受到多种因素的影响,其中包括气候变化。1972 年至 2020 年之间共有 28 个闰秒,闰秒之间的间隔可能很长。长时间的间隔会导致新技术的出现或发展,而工程师可能会忘记闰秒的概念,从而在系统中留下隐患。例如,2015 年和 2019 年的闰秒事件都导致了一些服务出现问题,而 2016 年间隔较短,问题相对较少。

一般来说,我们处理问题的次数越多,就越擅长应对它们。较长的升级间隔会增加知识丢失的风险,并且可能在构建关键功能时忽略了不可避免的问题。因此,缩短升级间隔可以确保工程团队在设计系统时考虑到这些问题,并且知道如何解决它们。

3. 存储驱动器故障应对

不同规模的存储系统对驱动器故障有不同的应对策略:
| 系统规模 | 应对策略 |
| ---- | ---- |
| 单台计算机 | 对于单台计算机的存储驱动器,其平均寿命为三到五年。可以通过定期备份数据来降低故障风险,并在驱动器最终故障时更换计算机。 |
| 数据中心 | 数据中心需要制定策略来防止驱动器故障影响运营。需要定期备份并能几乎即时恢复数据。数据中心通常有数千到数十万个驱动器,它们会不断出现故障。但当数据中心达到一定规模时,处理驱动器故障成为日常工作,就不会导致系统停机。 |

4. 自动化的注意事项

当无法完全消除系统中的恶化变化时,人们通常会选择自动化解决方案。例如,自动化更新 TLS/SSL 证书可以增加系统的安全性,因为证书的有效期可以更短。然而,自动化也存在问题。当自动化失败时,必须清楚问题出在哪里。如果自动化掩盖了系统的实际操作,或者让工程师忘记了系统的底层原理,那么在自动化失败时,就可能没有相应的安全措施。因此,自动化只有在明确责任人和故障状态能提供足够信息时才是有益的。

5. 正确地构建“错误”的系统

在系统构建过程中,不要在没有达到一定规模之前就追求大规模扩展。应该先构建一个简单的系统,即使它可能需要在后期重新设计。成功的复杂系统是由稳定的简单系统组成的。在系统能够通过负载均衡器、网状网络、队列等实用方法进行扩展之前,简单系统必须稳定且高效。

为了估计系统能够处理的复杂度,可以考虑团队的规模。一般来说,每个服务至少需要三个人来维护,最小的值班轮换团队需要六个人。例如,一个有 11 人的团队维护多个服务,当服务 A 需要向服务 B 发送数据时,有两种方案可供选择:
- 消息队列方案 :设置消息队列可以使 A 和 B 之间的通信解耦并具有弹性,这是最具扩展性的解决方案。但需要有人设置消息队列和工作进程,进行监控并在出现问题时做出响应。这种方案可能会导致团队责任不明确,某些部分可能会被忽视。
- HTTP 请求方案 :服务 A 直接向服务 B 发送 HTTP 请求是一种更简单的解决方案。这种方案内置了责任分配机制,如果错误发生在服务 B 端,拥有服务 B 的团队会收到警报;如果发生在服务 A 端,拥有服务 A 的团队会收到警报。虽然这种方案暂时失去了内置的容错能力,但从 HTTP 请求迁移到消息队列相对简单,更容易让当前团队维护系统。

下面是一个 mermaid 流程图,展示了服务 A 和服务 B 通信方案的选择:

graph LR
    A[服务 A 发送数据给服务 B] --> B{选择通信方案}
    B --> C[消息队列方案]
    B --> D[HTTP 请求方案]
    C --> E[设置和监控复杂]
    C --> F[责任不明确]
    D --> G[责任明确]
    D --> H[迁移简单]
6. 利用反馈循环管理团队工作

我们可以通过建立反馈循环模型来管理团队的工作。以服务 A 和服务 B 的维护为例,假设团队有七个人,每人每天工作八小时。服务 B 的团队负责两个服务,每个服务每天有四小时的预算;服务 A 的团队负责三个服务,每个服务每天有 2.5 小时的预算。

这个模型包含以下几个要素:
- 存量(Stocks) :技术债务会不断累积,通过花费工作时间来偿还;工作任务也是一种存量,团队在工作过程中会逐步完成这些任务;每天的八小时工作时间也是存量,系统稳定时,每天的八小时会被充分利用并恢复。
- 流量(Flows) :工作时间的投入会影响存量的变化。人们可以每天工作超过八小时,但这会降低最终的生产力,需要在后续减少工作时间。完成任务需要花费工作时间,工作时间的分配会影响技术债务和工作任务的存量。
- 延迟(Delays) :新工作不会立即取代旧工作,而是以一周为增量进行计划和分配。任务分配之间的时间间隔可以看作是延迟。
- 反馈(Feedback) :当存量发生变化时,会影响流量的性质。例如,人们工作超过八小时预算时,会失去未来的工作时间;过度投入某个服务的工作时间会导致其他服务被忽视,技术债务累积。

通过这个模型,我们可以模拟不同的工作场景,例如一个冲刺阶段有 24 小时或 70 小时的工作任务。当工作任务过多时,团队可能会面临以下几种情况:
- 团队将某个服务的所有权转移给其他团队,以增加每个服务的工作时间。
- 团队允许部分或所有服务的技术债务累积,直到某个服务出现故障。
- 团队成员过度工作,直到个人疲惫不堪,一段时间内无法工作。

为了重新建立平衡,团队可以改变系统设计,例如让服务 B 直接连接到服务 A 的数据库获取数据,这样可以减轻服务 A 团队的工作量,但可能会牺牲整体架构的质量。

总之,通过预见并应对软件问题、缩短升级间隔、正确处理自动化、合理构建系统以及利用反馈循环管理团队工作,我们可以提高软件系统的稳定性和可靠性,更好地应对未来的挑战。

软件未来-proofing:应对技术挑战的策略

7. 反馈循环模型的可视化与应用

我们可以将上述反馈循环模型进行可视化,以便更直观地理解团队工作的动态变化。以下是一个 mermaid 流程图,展示了该模型的主要元素和它们之间的关系:

graph LR
    A[工作小时] --> B[工作任务]
    A --> C[技术债务]
    D[团队规模] --> A
    E[服务数量] --> A
    F[日程安排] --> A
    G[倦怠程度] --> A
    A --> H[交付成果]
    B --> H
    C --> I[重构]
    H --> J[技术债务减少]
    I --> J
    J --> C

在这个模型中,工作小时受到团队规模、服务数量、日程安排和倦怠程度的影响。工作小时的分配决定了工作任务的完成情况和技术债务的偿还情况。交付成果的完成会带来额外的时间用于重构,从而减少技术债务。

我们可以使用一些工具来实际编程和探索这个模型,例如 Loopy(https://ncase.me/loopy/)和 InsightMaker(https://insightmaker.com/)。这两个工具都是免费且开源的,允许我们尝试不同的配置和交互。

8. 不同工作任务量下的模型分析

让我们进一步分析不同工作任务量下团队的应对情况。
- 低工作任务量 :假设一个冲刺阶段每个服务(服务 A 和服务 B)有 24 小时的工作任务。服务 A 团队每周有 50 小时的工作能力用于服务 A,服务 B 团队每周有 60 小时的工作能力用于服务 B。在这种情况下,每个团队都有足够的额外时间来处理技术债务,系统处于相对稳定的状态。
| 服务 | 团队工作能力(每周) | 冲刺任务量 | 剩余时间用于技术债务 |
| ---- | ---- | ---- | ---- |
| 服务 A | 50 小时 | 24 小时 | 26 小时 |
| 服务 B | 60 小时 | 24 小时 | 36 小时 |
- 高工作任务量 :如果一个冲刺阶段有 70 小时的工作任务,服务 A 团队需要每个成员从下周借用 5 小时才能完成任务。这样一来,团队将没有时间管理技术债务,并且下周只有 30 小时用于服务 A。如果这种高工作任务量成为常态,团队会逐渐疲惫,无法重新思考系统设计或管理债务,模型将变得不稳定。
| 服务 | 团队工作能力(每周) | 冲刺任务量 | 所需额外时间 | 下周可用时间 |
| ---- | ---- | ---- | ---- | ---- |
| 服务 A | 50 小时 | 70 小时 | 20 小时(每人借 5 小时) | 30 小时 |

9. 恢复模型平衡的策略

当模型出现不稳定时,团队可以采取以下策略来恢复平衡:
- 转移服务所有权 :将某个服务的所有权转移给其他团队,这样可以增加每个团队用于剩余服务的工作时间。例如,服务 A 团队将一个服务转移给其他团队后,就可以有更多的精力来管理服务 A 的维护责任。
- 允许技术债务累积 :团队可以选择暂时允许部分或所有服务的技术债务累积,直到某个服务出现故障。这种策略虽然会增加系统的风险,但可以在短期内缓解团队的工作压力。
- 调整系统设计 :如前面提到的,让服务 B 直接连接到服务 A 的数据库获取数据,这样可以减少服务 A 团队的工作量。但这种方法可能会牺牲整体架构的质量,需要谨慎考虑。

10. 对模型的进一步思考

这个反馈循环模型虽然提供了一种思考团队工作的方式,但也有其局限性。例如,它假设软件项目可以简单地通过增加人力来解决问题,这与 Fred Brooks 在《人月神话》中提出的观点相悖。实际上,软件项目的成功不仅仅取决于人力的投入,还与团队的协作、沟通和技术能力等因素密切相关。

然而,这个模型的重点不是规划路线图或预算人员数量,而是帮助人们将工程团队视为一个相互关联的系统。不良的软件往往是因为缺乏维护,而通过合理的规划和管理,我们可以提高团队的工作效率,确保软件系统的长期稳定性。

11. 总结与建议

为了应对软件系统中的各种挑战,我们可以总结以下建议:
- 预见问题 :在软件开发过程中,充分考虑各种极端情况,如时间误差、硬件故障等,及时发现并解决潜在的问题。
- 缩短升级周期 :定期进行系统升级,减少知识丢失的风险,确保团队能够应对不可避免的问题。
- 合理自动化 :在自动化解决方案中,明确责任人和故障处理机制,避免自动化掩盖系统的底层原理。
- 构建简单系统 :先构建稳定的简单系统,再逐步扩展系统的规模和复杂度,确保系统的可维护性。
- 利用反馈循环 :通过建立反馈循环模型,分析团队的工作状态,及时调整策略,保持系统的平衡和稳定。

通过遵循这些建议,我们可以更好地应对软件系统中的各种挑战,提高软件的质量和可靠性,为未来的发展奠定坚实的基础。

综上所述,软件未来-proofing 是一个复杂而长期的过程,需要我们在各个方面进行综合考虑和合理规划。只有这样,我们才能确保软件系统在不断变化的技术环境中保持稳定和高效。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值