架构决策中有一个特别“坑”的概念,叫做“最佳实践”!在决策时,情境(Context) 才是我们应该依赖的主要依据,而不是盲目遵循所谓的“最佳实践”。
“最佳实践”最多只能带来平均结果
咱们先说句让你有点蒙圈的话:“最佳实践”最多只能让你做得平平常常。 是不是觉得很奇怪?如果这东西是“最佳”的,那不是应该让大家伙都特牛吗?
这就好像,如果你想把我惹毛,不用说别的,直接来一句:“咱们就按‘最佳实践’来!” 我保证原地爆炸!为啥呢?你想想看,如果所有人都跟着同样的“最佳实践”走,结果为啥会差那么多呢?问题就出在这儿——“最佳实践”是为了那些普普通通、平均水平的情况量身定做的。
可你面对的系统、你的团队、你遇到的难题,它们可一点都不“平均”(希望是这样啦!)。
人体模型问题
咱们打个比方,你就能明白了。
你是不是在网上买过衣服?模特穿上那件衬衫,简直就是天衣无缝,怎么看怎么舒服,感觉穿上它自己都能变身时尚达人!结果衣服寄到了,打开一看,嗯,是那件没错,卖家也没坑你。你兴冲冲地往身上一套,走到镜子前……“Duang!”地一声,你被现实狠狠地击中了!这衣服简直是“惨不忍睹”!胸口紧绷,袖子松垮,你心里的那团火苗瞬间就熄灭了……是不是特沮丧?
是卖家故意骗你吗?不是!只是这件衣服它就是不适合你(你的身材)。卖家或者厂家在设计这件衬衫的时候,考虑的根本不是你这种体型的人。
当“最佳实践”变得不合理时
这事儿跟咱们盲目套用那些“架构模式”或者各种管理、领导模型是一个道理。这些东西在大会演讲上听起来超酷,在博客文章里写得天花乱坠,在演示程序里跑得溜溜的,需求也简单得要命。
可你的系统不是用来开会演示的啊!你的团队也不是写那篇“网红”文章的团队!你遇到的限制条件?那完全是两码事儿!
咱们再举个例子。想象一下,你公司有个内部报销系统。平时最多有多少人同时用呢?可能周一早上最忙的时候也就50个人吧。总共的用户量呢?公司就300个员工,他们宁愿去拔牙也不愿意再多填一份报销单!
现在你再想想这系统的架构:十七个微服务(为了所谓的“模块化”!),三个不同的消息队列(为了所谓的“解耦”!),还有一条连NASA工程师看了都要流口水的部署流水线!每次报销审批,都要涉及到七个服务。上传一张简单的发票,就变成了史诗级的“分布式事务”,简直比看《维京传奇》还复杂!
为啥有人要这么搞?哼,你懂的,还不是因为“最佳实践”就是这么说的!那些大公司(FAANG,就是脸书、苹果、亚马逊、奈飞、谷歌这些)都这么干的!在架构评审会上,这样搞才能得到大佬们赞许的眼神:“看看我们这可扩展性,多牛!”……可我们才50个用户啊……而且他们大部分都是朝九晚五的……午休时间也一样……
关键就在于——Netflix有2亿多用户,他们每天凌晨2点都在刷4K视频。他们遇到的挑战,你这辈子可能都遇不到,说实话,你可能根本不想遇到。当你照抄他们的解决方案时,你不仅仅是在照搬他们的模式,你还在照搬他们的问题!恭喜你,你把自己给坑了!
语境Context谱
咱们来对比两个完全不同的系统。
首先是高频交易平台。每秒钟几百万笔交易,每一笔交易都可能价值上百万美元。每一笔交易都必须被永久记录,不能被篡改。审计记录?那可不是“有最好,没有也行”的选择,那是“搞砸了就要蹲监狱”的硬性规定!所以,用“事件溯源”这种技术?完全合理!虽然复杂,但能让合规部门的人安心,这就值了。
现在,咱们去Joe's 披萨连锁店看看。有个小伙子(咱们叫他“架构师安迪”)读到了关于“事件溯源”的文章,他兴奋得不得了,真的非常非常兴奋!于是,他把这套东西用在了……餐桌预订系统上。
突然之间,取消5号桌的预订不再是简单的“UPDATE reservations SET status = 'cancelled'”了。哦不,那样太简单了!现在,它变成了一个“事件”!需要处理!需要预测!需要“最终一致性”!厨房的员工在谷歌上搜索“什么是最终一致性”,而顾客们则在纳闷,为啥取消一个桌子比做一张披萨还费劲!
同样的模式,同样的“最佳实践”。但背景却天差地别。一个赚得盆满钵满,另一个却……让人一头雾水。
产品与内部工具:两个世界的故事
做产品开发,就像是在亚马逊上预订了一场暴风雨,你知道它要来了,但你不知道它会变得多糟糕。你会是10个用户还是1000万用户?哪些功能真正重要?你基本上就是在把意大利面条扔到墙上,祈祷有东西能粘住(而且还能赚钱)。
内部应用呢?这就像你五年了一直沿着同一条路开车上班一样。你的用户?他们就是会计部的老王和人力资源的翠花。高峰负荷?周一早上,所有人都想起来要交报销单。最大的高峰?季度末,财务部突然发现他们急需这些报告。
然而,我们却眼睁睁地看着他们把内部工具造得像要上市一样!为了一个用户量跟隔壁小区卖柠檬水小摊差不多的应用,居然用上了Kubernetes集群来管理容器!精心设计的缓存层,就为了在水逆的时候(说实话,也就一个季度一次吧)更新数据!自动扩展的服务组,明明一台你抽屉里那台被遗忘的旧笔记本电脑就能跑起来!
与此同时,隔壁三栋楼之外,产品团队正对着他们的单体系统痛哭流涕,因为他们过于虔诚地遵循着“从简单开始”的信条。现在,他们正用胶带把服务器粘在一起,就因为有篇博客说“过早优化是万恶之源”。情况完全反过来了,而每个人都忙着搞“冲刺规划”,根本没注意到这一点。
平均问题
“最佳实践”是从那些成功的项目里总结出来的。听起来很有道理,对吧?关键是:当你把初创公司和大型企业的方法、“快速行动,打破常规”的文化和“一个bug就可能要命”的行业、B2C应用和内部工具的方法混在一起时,最后出来的可不是什么“超级实践”。
这就像把泰式咖喱、意式碳水化合物意大利面和德州烤肉混在一起,想创造一道“究极”美味。你知道你会得到什么吗?一道能让戈登·拉姆齐(那个脾气火爆的厨师)流泪……并且开始怀疑人生的大杂烩!
问题胜过答案
那么,除了盲目崇拜“最佳实践”之外,还有什么别的选择呢?
从提出问题开始!而且要问那些不好意思问、有点扎心的问题。
当“架构师安迪”又开始吹嘘他最新的模式™时,别只问“这是最佳实践吗?”而是要试着思考:
这东西到底解决了什么问题?
我们真的有这个问题吗? 是真有,还是只是觉得无聊?
以我们现在的规模,我们还能有这个问题吗?(剧透:你的内部应用不会成为下一个Facebook!)
这个模式对团队规模、系统负载和变化频率有什么假设? 这些假设跟我们实际情况符合吗?还是我们只是活在“架构师安迪”的幻想世界里?
再想想犯错的代价。如果我们现在不需要这种复杂性,那以后再加进去会多痛苦?如果我们确实需要它,却没有它,那到底会出什么问题?有时候答案是“没什么大不了”,这时候事情就变得有意思了。
无聊的优势
有件事你肯定不会被邀请去会议上发言:无聊也可以很美。
那个运行你内部工具的虚拟机?只要它能用,它就一定能用。那个你的开发人员真正理解的单体应用?或许没必要仅仅因为Twitter上有人这么说,就把它拆分成微服务。
我认识一家SaaS公司,他们的产品仍然是单体架构。一个!巨大!的应用!听起来是不是很恐怖!不过……他们盈利了。他们的开发人员不需要分布式系统博士学位就能追踪代码。他们的部署也不需要向Kubernetes之神献祭山羊。他们选择了“枯燥乏味”,而“枯燥乏味”也反过来选择了他们(还附赠了丰厚的利润)。
还有一家金融服务公司,他们运行的技术“老掉牙”到可能还记得COBOL当年有多火爆。科技圈的推特估计都快炸了。但你猜怎么着?他们的系统正常运行时间是以年计算的,不是什么“五个九”(99.999%),而是实实在在的“年”!客户把几十亿美元托付给他们,就因为他们的系统一直在稳定运行。
这些可不是什么“现代化”的失败。这恰恰是理解了真正重要的事情的成功。收入?有了。客户满意?有了。开发人员晚上睡得着觉?有了。最前沿的架构?……谁在乎呢?
你的约束就是你的超能力
那些大公司可比不上你的初创公司,你的公司能在一个漫长的周末,靠着能量饮料和一些“可疑”的生活选择,就把整个系统推倒重来。同样,初创公司也比不上你的大企业,大企业可以用钱解决问题,直到问题乖乖投降。不同的环境,不同的“超能力”。
当你拥抱自己的环境而不是与之对抗时,你才表现得像个大人。当别人被复杂性淹没时,你可以做得更简单。当别人需要开十七次会议才能审批一件事时,你可以行动得更快。你可以针对真正对你的用户重要的东西进行优化,而不是针对2019年某个会议上某个人关心的事情。
“几乎正确”的陷阱
这里有个小秘密——要小心那些“几乎”适合你情况的做法。 这些做法特别危险!它们足够接近你的情况,所以你不会深入思考;但它们又足够不同,以至于它们会像你怀疑是不是坏掉的剩饭剩菜一样,慢慢地“毒害”你的架构。
你知道那种感觉。每个功能都感觉像是在和自己的建筑较劲。简单的改动都需要复杂的仪式,连梵蒂冈都会嫉妒。你的模式感觉像是在主动给你使绊子。这通常是你的环境在试图告诉你一些事情……如果你愿意听的话。
找到自己的路
卓越不是靠复制粘贴别人的作业得来的。卓越源于理解你自己的任务。
你的用户(是只有十二个,还是一千两百万个)。
你的限制(预算、时间或者你的理智——选一个吧)。
你的能力(你的团队真正了解什么,而不是他们在领英上吹嘘的那些)。
“最佳实践”可以给你一些启发,但它绝不能取代你自己的思考。这就好比你用GPS导航自己的客厅一样。技术上可行,但……为啥要这么做呢?
下次有人在设计评审会上抛出“最佳实践”这个词时,深吸一口气,数到三。然后问:“对谁来说最好?在什么情况下?在什么限制条件下?” 看着他们开始思考的样子,享受这份短暂的宁静吧。
“不负责任的机器”
你猜丹·戴维斯(一位学者)会怎么看这事儿?在他的书《不负责任的机器》里,他一针见血地指出,组织是如何建立复杂的系统来逃避实际决策的。听起来是不是很熟悉?“我们只是遵循最佳实践”在建筑领域,就等同于“我只是在服从命令”。
这些做法成了挡箭牌。不能怪我把系统搞得过度复杂——我遵循的是Netflix的架构啊!不能怪我们的选择——我们采用了行业“最佳实践”啊!这就像一场“甩锅”闹剧。我们躲在自己制造的复杂性背后,当事情出了问题时,就把责任推给那些会议演讲和博客文章。
真正的责任?理解你所处的环境,做出你自己的选择,承担你自己的决定。 即使这些决定从某种“武断”的标准来看是“错误”的。至少它们是你自己的。
架构师警报! ⚠️
即使是经验丰富的架构师也会掉进一个陷阱:“最佳实践”变成了教条。一开始是“这在某种情况下很有效”,后来却变成了“你必须一直这样做,否则就会面临架构审查委员会的怒火!”。
当你听到自己说“但谷歌/Netflix/亚马逊不是这么做的”时——停下来!完全停下来! 你不是谷歌。你的问题不是他们的问题。他们的解决方案实际上可能会毒害你的系统!
注意以下警告信号:
- 每个简单的功能都需要比代码本身更长的设计文档。
- 你的架构图看起来像现代艺术(而且同样让人看不懂)。
- 新来的开发人员需要有分布式系统博士学位才能给按钮添加功能。
- 你正在解决你永远不会遇到的问题,却忽略了那些摆在你面前的真正问题。
真正的技能?知道何时打破规则! 我认识的优秀架构师对“最佳实践”都有一种健康的“不尊重”,他们执着于理解自己实际的环境。
总结
盲目遵循“最佳实践”有其固有限制:
- 忽略具体情况Context: 它们往往是为“平均情况”优化的,却忽视了每个组织、团队、系统和挑战的独特情况Context。例如,Netflix为了2亿用户设计的复杂架构,对于只有50个用户的内部系统来说,就是过度设计。
- 导致平庸: 如果每个人都遵循相同的方法,那么结果也只能是相似的,难以产生超凡的创新或突破。你无法通过模仿别人来超越别人。
- 引入问题: 照搬别人的“最佳实践”,往往也意味着你同时继承了别人解决复杂问题时所面临的挑战和复杂度。
- 扼杀创新: 当“最佳实践”成为教条时,它会限制思维,阻碍探索新的、更适合自身情况的解决方案。
情境悖论 (The Context Paradox)
“情境悖论”则强调了“最佳实践”的局限性,具体情况决定适用性: 任何看似“最佳”的方法,其有效性都高度依赖于特定的情境、条件和限制。脱离了特定的情境,原本的“最佳实践”可能就变得毫无意义,甚至适得其反。
矛盾共存: 悖论意味着两种看似矛盾或对立的事物,在特定的语境下却可以同时存在并发挥作用。在“最佳实践”的情境悖论中,这种矛盾体现在:
- 某个方法在A情境下是最佳,但在B情境下却很糟糕。
- 你试图通过“最佳实践”来解决问题,但这个实践本身可能又在你独特的情境中制造出新的问题。
- 追求普遍的“最佳”反而可能导致局部或特定情况下的“次优”。
好好想想你现在的项目。认真思考一下。你遵循的哪些“最佳实践”让你感觉像是戴着别人的近视眼镜?哪些“不走寻常路”的选择实际上可能对你更有利?如果你根据自己的情况进行优化,而不是根据一些虚构的平均值进行优化,会发生什么?
记住:最有趣的架构,并不是那些遵循所有规则的架构。而是那些知道打破哪些规则、何时打破规则、以及为什么打破规则对他们来说是合理的架构。
没有放之四海而皆准的万能药!你的情况Context独一无二,你面临的挑战具体而明确,你的解决方案也应该如此。