冗余比优雅重要,根本没有完美的代码

95 阅读5分钟

这是一场关于 「控制 vs. 混沌」 的根本性讨论。让我们大胆剖析:


主流观点:

非程序员通常认为:“代码写得好,系统就不会崩溃。”
这种观点可以追溯到对技术的一种朴素理解:完美的设计和执行 == 没有错误。问题看似只存在于人类的疏忽和不严谨。这种思维将代码视为唯一变量,而忽略了其运行环境的复杂性。


程序员的对立认知:

系统崩溃的主要来源往往并非代码,而是外部环境的不可控性:

  • 网络抖动:即使代码完美,突然丢包、超时也会让你系统直接“失联”。
  • 硬件故障:内存泄漏、磁盘损坏、CPU过载,再好的代码也顶不住。
  • 第三方系统不靠谱:上游 API 突然改个字段,下游服务毫无提示挂掉;再完美的代码也无法补救。
  • 用户操作超预期:1亿用户突然点了同一个按钮;垃圾数据输入;非程序员喜欢说“你没验证好用户输入”,但实际上,用户能带来的问题远比你想象得离谱。
  • 边缘案例爆发:几乎没有人设计系统时会对“2年后元旦凌晨全球时间戳溢出”有预见,但现实中这种事情经常发生。

这里的核心逻辑是:复杂系统中的崩溃并不总能通过“内部优化”解决,很多问题是“系统之外”的混沌注定要出现。


让人不舒服的强观点:

代码质量的重要性被过度高估,真正决定系统稳定性的,往往是环境设计的冗余性。

这话很刺耳,但用实例说话更有力。来看几个案例:

  1. 谷歌搜索的设计哲学
    谷歌搜索的代码“完美”吗?不可能。大规模分布式系统中,Bug 是一种常态。然而,谷歌依赖的是极致的冗余性和容错设计:比如每条用户查询会被分发到几十个副本服务器,单个节点宕机不会对体验造成影响。这是对混沌环境的正视,而非对代码完美的迷信

  2. 亚马逊的 Black Friday 宕机
    2018年的黑色星期五,亚马逊的一些核心服务因“外部流量超载”而宕机。系统压测了几个月,代码质量已经足够高,但依旧扛不住外部不可控变量的叠加:假如一个节点负载 100%,不只是这一节点会崩,连锁反应会导致整套系统失灵。

  3. SpaceX 的火箭重用设计
    大家都知道 SpaceX 火箭的自动控制代码多么复杂,但它的成功依赖的不仅是“完美代码”。火箭的每一个传感器冗余设计、实时数据流的校验、地面与卫星的环境适配……外部环境占了绝对主导。换句话说,即使代码写得再好,如果雷暴突袭、风速超标,发射依旧失败。


鲜为人知的真相:

系统设计的成败并不取决于代码是否“完美”,而在于它是否足够丑陋地承认现实的不可控性。一些看似“不够优雅”的防御性编程、备份设计和环境模拟,才是真正拯救系统的关键。

比如:

  • AWS 的“混沌工程”:Netflix 和 AWS 会故意引入人为的系统故障(例如直接关掉随机节点),并研究系统如何在崩溃中恢复。代码的“完美”在这里毫无意义,抗脆弱性才是重点。
  • 分布式系统的“CAP 定律”:一致性、可用性和分区容忍性无法同时实现。程序员必须承认并妥协于系统永远有“不完美”的地方。

最具争议的观点:

“代码问题”其实是系统崩溃后被人类找的替罪羊。

为什么这么说?因为:

  1. 外部环境不可控,难以追责:没人能直接指责“网络抖动”或“硬盘崩溃”,但代码永远是可见的、可修改的。人们的心理倾向是:寻找清晰的责任对象。
  2. 非技术人员无法理解环境问题:一个项目经理看到报错日志时,会直觉认为:“这段代码写得有问题。”但网络丢包的那一瞬间,他根本没意识到“根本原因可能与代码无关”。
  3. 程序员对“环境失控”有默认的无奈:很多时候,他们只是默默修补错误,而不会试图让外人理解根本原因。

举例:某银行核心交易系统崩溃后,最终“定位”到某行代码少了一个边界值判断。然而,真正的原因可能是第三方供应商的服务挂掉,导致传入了垃圾数据。可惜,没人会在报告里写上“第三方不靠谱”,因为这听起来像推卸责任。


总结:

“代码”从未脱离过它运行的环境。追求代码完美,是一种奢侈的错觉;追求环境冗余,才是对抗混沌的唯一解。

如果你强迫系统完全依赖代码质量,那么你注定失败。与其痴迷于完美的代码,倒不如承认环境的混乱,并设计一个“即使在最糟情况下仍能运行”的系统。