推荐这篇,Dan McKinley(前 Etsy 工程师)写的经典工程文化文章。他说每个公司大约有三次"创新 token"的机会——你选了 NodeJS、MongoDB、使用不到一年的服务发现技术,每次都是花掉一次。而选 MySQL、Postgres、Python、Cron……这些无聊技术的好处在于,不仅功能被充分理解,失败模式也被充分理解。这不是一篇反对新技术的文章——是教你什么时候该用新技术、为什么要给团队设定"使用新东西需要全公司知道"的文化。
选择无聊的技术
我职业生涯中发生的最好的事,大概是有 Kellan 管我。我在那里待得够久,看到了 Kellan 的技术决策开始结出果实。我从中并且作为其结果学到了很多东西。
离开 Etsy 一年后,我重新恢复了对技术的关注能力。我的思考已经结晶到可以连贯地写下来的程度。以下是 Kellan 式思考的总结——希望不会让他太过尴尬。
拥抱无聊
设想每个公司大约有三个创新 token。你可以随心所欲地花它们,但供应量在一段长时间内是固定的。你也许在达到一定程度的稳定和成熟之后能再多拿到几个,但一般倾向是高估你钱包里有多少。
如果你选择用 NodeJS 写你的网站,你刚花掉了一个创新 token。如果你选择用 MongoDB,你刚花掉了一个创新 token。如果你选择用存在了一年或不到的服务发现技术,你刚花掉了一个创新 token。如果你选择自己写数据库——天哪,你麻烦大了。
这些选择中任何一个对一家 JavaScript 咨询公司或一家数据库公司可能是合理的。但你大概率不是。你大概率在为一家至少表面上是"重新思考全球商务"或"重新发明网络支付"或推进某个同样适当宏大的使命的公司工作。在这个背景下,把你有限的注意力用在创新 SSH 上,是一种极好的失败方式。或者至少是延迟成功的方式。
什么算无聊?这有点微妙。"无聊"不应该和"坏"混为一谈。世界上有既无聊又坏的技术——你不应该用这些。但有很多无聊且好的技术选择,或至少足够好。MySQL 是无聊的。Postgres 是无聊的。PHP 是无聊的。Python 是无聊的。Memcached 是无聊的。Squid 是无聊的。Cron 是无聊的。
无聊的美妙之处(如此定义下)在于这些工具的能力是被充分理解的。但更重要的是,它们的失败模式也是被充分理解的。
在选择技术时,你既有已知的未知,也有未知的未知。
• 已知的未知是类似这样的:"我们不知道这个数据库达到 100% CPU 时会发生什么。"
• 未知的未知是类似这样的:"老天,我们甚至没有想到写统计量会导致 GC 暂停。"
哪怕对于已经存在了几十年的技术,这两种集合通常都是非空的。但对于闪亮的新技术来说,未知的未知的量级要大得多——这很重要。
全局优化
我毫无歉意地认为偏袒无聊技术是一件好事,但它不是唯一需要考虑的因素。技术选择不是在孤立状态下发生的。它们有一个影响范围,触及整个团队、组织,以及从你所有选择之和里涌现出的系统。
向公司添加技术是带成本的。作为一个抽象陈述这很显而易见:如果我们已经在用 Ruby,再加 Python 感觉不合理,因为增加的复杂性会超过 Python 的边际效用。但不知何故当我们谈论 Python 和 Scala 或 MySQL 和 Redis 时,人们失去了理智,抛弃了所有约束,开始狂热地谈论为任务选最佳工具。
你的工作本质上是将业务问题映射到一个涉及软件选择的解空间上。如果软件选择真的没有包袱,你确实可以为你各种各样问题挑一堆局部最佳的工具。
但在现实世界里——那个运维是严重关切的世界——你是在全局优化。问题在于"最佳工具"思维对它眼中的"最佳"和"任务"是近视的。你的任务是保持公司运转。而"最佳"工具是那个在尽可能多的问题上占据"最不差"位置的工具。
保持系统可靠运行的长期成本基本上总是远远超过你在构建时遇到的任何不便。成熟和多产的开发者理解这一点。
有时选择新技术
把这种推理推到归谬的极端,就是选 Java,然后尝试不借助任何其他东西来实现一个网站。那将是疯狂的。你需要一些向工具箱里添加东西的方法。
重要的第一步是承认这是一个过程,以及一场对话。新技术最终会产生公司层面的影响,所以添加技术是一个需要公司层面可见度的决定。
最值得推荐的练习之一是:考虑如何在不添加任何新东西的情况下解决你的当前问题。 首先,提出这个问题应该能检测到"问题"其实是有人真的想用这项技术的情况。如果是这样,你应该立即否决。
一个小的技术选择集合能走多远,可能令人惊讶。实践中这个问题的答案几乎从来不是"我们做不到",它通常只是某种程度上的"嗯,我们可以做到,但会太难了"。如果你认为你用现有的工具无法实现你的目标,你大概只是不够有创造力地思考。
写下到底是什么让当前技术栈如此昂贵和困难地解决问题,这会有帮助。这和上一个练习相关,但有微妙的不同。
新技术选择可能是纯增量式的(比如:"我们还没有缓存,所以让我们加 memcached")。但它们也可能与你已经在使用的东西重叠或替换它。如果是这样,你应该为将旧功能迁移到新系统设定明确的期望。 策略通常应该是"我们承诺迁移",带有建议的时间线。这一步的目的是把残骸保持在可管理的水平,并避免局部最优解的泛滥。
这个过程并不令人生畏,也不麻烦。就是几个填空题作为作业,然后开个会讨论一下。我认为,如果一项新技术能毫发无损地通过这个挑战,加入它是可以的。
发版就好
多语言编程被包装成一个承诺:让开发者以完全的自由选择自己的工具,会使他们更有效地解决问题。这个问题的定义往好了说是幼稚的,往坏了说是动机性推理。这种方式产生的日常运维苦力的重量把你压死。
有意识地选择技术给了工程头脑真正的自由:沉思更大问题的自由。为技术而技术是万金油。
原文:Dan McKinley, "Choose Boring Technology", 2015
#
工程文化# #
技术选型# #
无聊技术#