Alex Gaynor

嗨,我是 Alex。我是一名软件弹性工程师。我关心构建可用的系统。我曾在政府部门、私营部门和开源领域工作。我的工作地点在华盛顿特区。

© 2025. All rights reserved.

Postel's Law and the Three Ring Circus

2025年3月25日,星期二

Postel’s Law 著名的指出:“实现应遵循鲁棒性的一般原则:在自己做的事情上要保守,在接受来自他人的东西时要开明。” 多年来,这被认为是互联网生态系统的基石设计原则,但近年来它已经失宠。 在这篇文章中,我将解释努力遵循 Postel’s Law 的生态系统经常经历的恶化,以及为什么它会在开源软件的背景下产生特别有害的结果。

Postel’s Law 的一般主张是,生成(或发送或序列化)数据的软件应该是 conservative 的,也就是说,它应该严格遵循相关的规范; 以及消费(或接收或解析)数据的软件应该是 liberal 的,也就是说,它应该允许偏离相关的规范。 这被认为可以提高鲁棒性,因为它允许数据消费系统即使在数据生产系统存在一定程度的错误的情况下也能继续运行并接受数据。

这是一个关键的观察:如果每个人都遵循 Postel’s Law,那么就不需要任何人在他们接受的东西上采取 liberal 的态度,因为每个人都会在他们生产的东西上采取 conservative 的态度。 但是,因为人们实际上 not 在他们生产的东西上采取 conservative 的态度,所以消费者必须在他们接受的东西上采取 liberal 的态度。 实际上,这意味着存在不对称的义务:因为我们知道生产者不会遵循 Postel’s Law,所以消费者必须遵循它。 因此,遵守 Postel’s Law 的生态系统会经历单向棘轮效应:消费者必须接受越来越多的与规范的偏差,并且因为消费者接受这些偏差,所以生产者永远不会被迫(或激励)自己在遵循规范方面变得更严格。 随着时间的推移,偏差正常化

一个试图遵循这一原则的生态系统,经过几次进化上的曲折之后,会发现自己处于一种存在许多问题的状态。 首先,将很难描述系统的精确行为是什么,因为虽然大多数消费者接受各种与书面规范的偏差,但无法保证它们都具有相同的行为,并且没有任何地方记录了哪些偏差在实践中是必需的。 其次,通过阅读规范(或者实际上,任何书面文档)来创建新的实现将变得不可能,新的实现将需要构建真实世界数据的语料库来进行测试,或者随着用户尝试在真实世界场景中使用它们,迭代地使自己变得更加宽松。 最后,对书面规范进行更改将更加困难,因为很难知道它们是否与野外使用的实现的实际行为不兼容。

我想花一点时间专注于这些问题中的第二个问题:需要采取 liberal 的态度来接受未记录的与规范的偏差,这使得创建规范的新实现变得困难。 这充当了新实现的进入壁垒,从而减少了生态系统中实现的数量。 更少的实现意味着更少的竞争。 竞争以产生最佳实现是我们改进安全性、性能和可读性(或最佳情况是,沿着多个轴帕累托最优改进)的最佳方式之一。 因此,遵循 Postel’s Law 的生态系统的适应不良压力会产生进化死胡同,在任何方向上的改进都很少见。 事实上,在这种生态系统中,最强大的竞争压力将是:任何其他实现接受的任何格式错误的数据都必须被所有实现接受。

在开源的背景下,这些压力尤其有害。 想象一下有三个参与者的情况:1) 一个生成数据的闭源产品,2) 一个消费数据的开源项目,3) 一个尝试使用开源软件解析来自闭源产品的数据的用户(我称这个群体为三环马戏团)。 我们已经知道 Postel’s Law 不对称性的基本动态:如果生产者偏离规范,那么有一种强烈的趋势认为消费者有责任更加自由并接受(原则上)格式错误的数据。 但是,当其中一个参与者是开源项目,而另一个参与者是商业项目时,会产生额外的扭曲效应:开源项目更容易被投诉。 实际上,所有开源项目都有公共错误跟踪器,任何人都可以在其中提交问题,并且开发人员会直接收到这些问题。 相比之下,商业项目不提供对其错误跟踪器的直接访问,错误而是通过仅对付费客户可用的支持系统进行调解,并且必须由支持人员进行分类,然后才能传递给开发人员。 简而言之,开发人员遇到开源项目严格拒绝闭源产品生成的数据的情况,他们向开源项目投诉会容易得多,无论偏离规范是多么不合理。 因此,人们会向正确实施规范的志愿者维护者投诉,而不是向未正确实施规范的大型商业软件供应商投诉。

由于这些原因,我鼓励软件工程师,尤其是开源维护者,在遵循规范方面要严格,并在仍然拥有有用的软件的前提下,尽可能地拒绝与规范的偏差。 特别是,我鼓励维护者拒绝用户反馈,这些反馈更应该直接发送给未正确实施规范的商业软件供应商。 如果您是真正希望宽松解析行为的标准作者,正确的解决方案是在所有情况下记录您想要的行为,就像 HTML5 规范所做的那样。 但是对于所有其他规范,我们需要拒绝变得越来越宽松,并且越来越脱离规范的无休止的螺旋。