在技术选择上,应当优先考虑成熟、稳定甚至“无趣”的方案,而不是追逐最新的潮流。每引入一项新技术,都会消耗公司有限的“创新配额”并增加长期的运营负担。真正的目标是为整个系统进行全局优化,而不是为单个问题寻找所谓的“最佳工具”。只有在经过深思熟虑,确认现有工具无法解决问题后,才应谨慎地引入新技术,这能让团队从琐碎的维护工作中解放出来,专注于解决更重要的业务问题。
拥抱无趣的技术
每家公司大概只有三个“创新配额”。你可以随意使用它们,但这个配额在很长一段时间内是固定的。当你达到一定的稳定和成熟度后,或许能得到一些补充,但人们往往会高估自己拥有的配额。
这是一个简化的模型,但很有帮助:
- 如果你选择用 NodeJS 写网站,你就用掉了一个创新配额。
- 如果你选择用 MongoDB,你就用掉了一个创新配额。
- 如果你选择使用一个存在不到一年的服务发现技术,你也用掉了一个创新配额。
除非你是一家数据库公司或 Javascript 咨询公司,否则这些选择可能并不明智。你的公司可能正在试图重塑全球商业或革新在线支付。在这样的背景下,将有限的精力投入到“创新”基础技术上,是通往失败的捷径,或者至少会拖延成功的步伐。
无趣不等于糟糕
“无趣”不应该与“糟糕”混为一谈。有些技术既无趣又糟糕,你应该避开它们。但更多的是那些无趣但足够好的技术。
- MySQL 是无趣的。
- Postgres 是无趣的。
- PHP 和 Python 是无趣的。
- Memcached 是无趣的。
- Cron 是无趣的。
这些无趣技术的好处在于,它们的能力和局限性都已广为人知。更重要的是,它们的失败模式也已众所周知。
在选择技术时,你总会面临“已知的未知”和“未知的未知”。
- 已知的未知:我们不知道这个数据库在 CPU 达到 100% 时会发生什么。
- 未知的未知:我们根本没料到写入统计数据会导致垃圾回收(GC)暂停。
对于新技术而言,“未知的未知”的数量要大得多,这是一个巨大的风险。
全局优化,而非局部最优
技术选择会影响整个团队、组织和系统。增加一项新技术是有成本的。人们很容易理解,如果已经在用 Ruby,再引入 Python 会增加不必要的复杂性。但当谈到 MySQL 和 Redis,或 Python 和 Scala 时,人们似乎就忘记了约束,开始鼓吹“为工作选择最佳工具”。
你的工作是让公司持续经营下去。“最佳”工具应该是那个能在尽可能多的问题上处于“最不差”位置的工具。
所谓“为工作选择最佳工具”的思维方式,其视野是狭隘的。它忽略了技术选择带来的“包袱”——也就是运营和认知开销。你需要监控它、为它写单元测试、学习如何维护它。这些成本会迅速累积。
一个系统的长期维护成本,几乎总是远远超过构建它时的任何不便。成熟的开发者明白这一点。
如何谨慎地引入新技术
当然,这不意味着你只能用 Java 实现所有东西。你需要一个流程来为你的工具箱添加新成员。
首先,要承认这是一个需要公开讨论的过程。
一个有价值的练习是:思考如何用现有工具解决当前问题。这能帮你识别出那些只是因为“某人想用新技术”而产生的问题。如果你发现是这种情况,应该立即停止。
如果你认为用现有技术无法实现目标,很可能只是你思考得不够有创造力。
如果确实需要新技术,可以遵循以下步骤:
- 写下当前技术栈的局限性:准确说明为什么现有工具让解决问题变得极其昂贵和困难。
- 制定迁移计划:如果新技术会替代现有功能,应承诺一个迁移时间表,以避免技术栈的无序扩张。
这个过程并不繁琐。如果一项新技术能经受住这些拷问,那么引入它就是合理的。
真正重要的事:交付产品
允许开发者自由选择工具,并不能让他们更高效地解决问题。这种做法只看到了问题的表面,其产生的日常运营负担最终会将你压垮。
在 Etsy 早期,我们曾为活动推送功能选择了一套“无趣”的技术栈(PHP、MySQL、Memcached)。这个实现比使用 Redis 更复杂。但令人惊讶的是,在接下来的几年里,我们几乎没有关注它,而它的规模却增长了 20 倍,一切都运行良好。这就是技术选择上保持克制的长期好处。
明智的技术选择能给予工程师真正的自由:去思考更宏大的问题。为了技术而技术,只是在浪费时间。