新的一集
嗯,已经 2026 年了。
如果你翻翻我上一篇博客——没错,那已经是四年前了:我在亚马逊开始了人生第一份正式的工程师工作。这四年发生了太多事。我刚被裁了,但说真的,我居然还觉得自己挺幸运。
重头戏来了:我确实享受在亚马逊的日子,但到后面,它越来越不“刺激”,也越来越不像是在学习了。所以从某种意义上,我甚至觉得自己赚到了——亚马逊等于给我发了一笔“转行补贴”,鼓励我去换个环境继续成长。
总之,下面这些就是我过去四年里学到的有趣东西(当然,不会违反 NDA)。
我是在 2022 年情人节那天入职亚马逊的,被分到了一个叫 Your Orders 的团队(负责“订单相关体验”的一整套页面与服务)。这个团队最出名的产品,就是 Amazon.com 上的 订单历史 页面(以及除美国以外的各个站点)。我们也负责一些其他页面,比如 订单详情、面向移动端的一些订单/购买相关入口页。
我到现在都记得入职前跟经理的第一次一对一沟通。我问她:这是我第一次真正进入科技行业,我应该提前做点什么准备?她说:“读《Effective Java》吧,是个不错的开始。”
我很听话:买了书,读完了。
然后三个月后我发现——我做的大部分改动,都在 Perl-Mason 上(Perl 语言的一套网页/模板框架,偏“老牌 Web 栈”那一类)。
我对 Perl 的理解程度,大概和我对“如何开发量子计算机”的理解差不多:接近于零。
那你可能会问:既然我们天天写 Perl,为啥经理一上来叫我学 Java?
答案很简单:亚马逊很“老”。
1994 年亚马逊刚开始在网上卖书的时候,贝佐斯还在搞门板(door panel)那种“车库创业”级别的活。到 1997 年左右,亚马逊开始卖的不只是书了,于是他们做了一个叫 Obidos 的东西。它是早期的“大一统网站架构”,你可以理解成一个超级单体。
说它是“架构”都抬举它了,它更像一个巨大到离谱的大包:一个包,装下了整个世界。
后来工程师发现这玩意根本不好扩展(那肯定的),于是又开了一个新架构:Gurupa,名字来自巴西帕拉州(Pará)的亚马逊河支流。这个 Gurupa 完全用 Perl-Mason 写的——这种东西我在学校里根本不可能学到。
顺便一提:亚马逊和 IRS 之间有过一个诉讼,判决书里居然带了不少 Gurupa 的技术细节,属于“法律文书里掺技术干货”。链接在这:here。
好,那新的问题来了:
既然 Gurupa 已经是升级版了,为啥后来还要迁移到 Java?
(以下属于“我没跟 CTO 或贝佐斯开过会,但我会用十足自信来推测”的部分。)
第一点:因为它是 Perl。
你写 Perl 有一种很神奇的体验:你回头看自己三个月前写的代码,会觉得像在阅读陌生人留下的密室遗言。你得盯着它看一会儿,才能想起来:“哦……原来我当时是这个意思。”
如果作者还不爱写注释、变量名随缘,那就更刺激了。我曾经花了好几个小时翻 Perl 文件,就为了搞懂那个 $s 到底是什么东西,以及为什么它能调用一个在 package 里根本没定义的函数。
这也解释了为什么 Perl 很难成为大学课程里的老师最爱语言。二十年过去,新一代工程师(比如我)基本都不会读、也不会写 Perl 了。
第二点:亚马逊很难再招到愿意写 Perl 的新人了。你不能指望 2020 年后毕业的人,突然热爱 2000 年代的 Perl-Mason 生态。
第三点(也是关键):Gurupa 其实还是单体。
(单体架构:很多功能堆在一个巨大应用里,改动和发布容易互相牵连。)
说白了就是:贝佐斯把一个单体换成了另一个单体(只是更好一些:至少大家可以“拥有”自己的一块服务包,不至于全员共用一坨泥)。但单体的本质没变:部署还是得集体协调。
每周部署都像集体开会:互相交叉检查,确认自己不会成为那个“一个提交卡住全公司发布”的罪人。
所以你就理解了:改是一定要改的。
我在亚马逊的大部分时间,都在做一件事:把那套又大又老的 Perl 技术栈迁移到 Java,以及围绕这个迁移目标衍生出来的一堆项目。
而且这件事不仅该做,还是早就该做——按理说应该在我入职之前就迁完了。
难点也非常现实:我们服务全球 30+ 个站点,同时新站点还在不断上线。迁移过程中必须做到两件事:
1) 客户最好完全感觉不到变化;
2) 我们要一边支持从 1995 年以来所有历史遗留功能,一边继续发新功能。
简单总结:边开车边换发动机,还不能让乘客察觉抖了一下。
前三年,我的主要精力就是“新 Your Orders 页面”的建设。
那段时间我第一次感受到什么叫“大厂体系”:酷的东西多到让人晕眩。前几个月我直接被淹没,冒名顶替综合症拉满。
构建系统(Brazil——亚马逊内部的构建/依赖/发布相关工具链之一)、原生流水线(自动化 CI/CD 流程,负责构建、测试、部署)、代码化监控(监控规则也像代码一样可版本化管理)、工单系统(处理需求/缺陷/事故的流程平台)、联邦系统(federation system:把页面需要的数据/组件从多个后端聚合到一起的机制)、无代码微服务(codeless microservices:用配置/模板生成、少写业务代码的服务形态)……你能想到的都能在那儿看到。
入职第二年,我开始做一个“属于自己的项目”:把页面处理支付出错的逻辑从 Perl 迁移到 Java。
以前的做法大概是这样的:页面有一个中央控制器(page central controller:页面请求的“总入口/总调度”),它去调用支付相关的依赖,然后把生成的文案“直接在页面内容里就地替换”。我们想摆脱这种模式。
因为“就地替换”意味着:你把一堆支付业务逻辑塞进了页面控制器里。
像这样:
page.allPreparations();
alert = page.callPaymentDependencyAndTransformIntoPresentableAlert()
page.getAllContent()
if (alert) page.order.text.replaceWith(alert);
page.render()
这当然不妙。
把业务逻辑塞在前端服务里,本身就已经很糟了;更糟的是,那些业务逻辑我们甚至不拥有、也不真正理解。我们只是“展示订单页面”的团队,却要在前端处理“支付世界观”。
好消息是:我们的系统本来就是分层的,业务逻辑、展示逻辑、呈现逻辑各司其职;再加上我们团队刚好做了一个 federation system。
这个 federation system 的作用可以理解成:我们可以构建一个独立应用,专门负责根据不同 use case 产出“可以直接展示”的页面定制内容,然后由页面去消费这些结果——页面不需要懂业务,只需要展示。
于是我把范围定义清楚,去对齐不同团队,梳理各种支付方式(全球在亚马逊买东西的支付方式多到离谱;比如在日本你甚至可以去 711 现金付款),把一堆边缘情况逐个补齐。
更有意思的是:这个项目其实在我入职之前就有人建了,但因为归属复杂、人员流动、协调成本高,一直没真正推进。直到我把它捡起来,它才终于跑起来。
所以我决定给自己颁个小奖杯:🏆(允许我自嗨一下。)
这里还要提一下 Datapath(一个面向低延迟的数据访问/聚合平台,强调“快”和“能 join 多源数据”)。想更直观理解平台可以听这个:here。我当时带着一个执念去读他们代码:他们到底怎么在极低延迟下处理复杂逻辑依赖?
只能说——我读到的实现,真是漂亮。
我还有很多好玩的开发故事可以写,但再写下去这篇会太长,所以我先讲讲运维这一面,开发故事留到下次。
我真的非常非常庆幸自己进了一个负责亚马逊最关键页面之一的团队。对一个刚毕业的人来说,能直接摸到 每秒 3 万+ TPS 的系统(TPS:transactions per second,每秒处理的请求/交易量),这简直是“新手村直接进地狱副本”,但偏偏你还能活下来、还能学得很爽。
对比一下:我的个人网站大概只有 0.0005787 TPS。
在这种环境里,你会被迫学会怎么把分布式系统设计对——不然黑五流量涨三倍的时候,系统就会用崩溃告诉你什么叫现实。
你可能以为这种团队天天被事故轰炸,特别是 sev-2+ 级别的事件(事故严重等级 2 及以上)。但说实话:我最后一轮 oncall(值班轮值:随时响应线上问题)只被 page 在白天叫过两次,黑五期间一次都没有。
这不是运气,这是“好设计 + 好代码 + 好监控 + 主动预防事故”的结果。
而且最离谱的是:我在 oncall 周学到了很多,却完全没有被压垮——如果你对比其他公司或团队(AWS,懂的都懂),你会知道这有多不常见。
当然,客服工单还是会有的,而且有些工单非常“人类观察学”。
比如我处理过一个:客户说“没连 Wi-Fi 的时候看不到订单”。
还有一个经典:客户说“看不到物流信息”,然后我一看设备:Android Lollipop(2014 年 11 月发布)。
兄弟,我也没法替你的老古董手机做啥……我最多只能帮你在亚马逊上挑个新手机。
回头看,压力确实是越来越大了。不是因为事情更难,而是因为你知道得更多——你开始看到系统哪里可以更好、流程哪里能优化、工具哪里该升级。
去年我花了不少时间优化自己的工作流,同时也推动团队工作流变得更顺。
我也上线了不少功能。如果你在亚马逊 App 里看到 “Ask about your purchases” 那些小药丸(pills:App 里的小提示/快捷入口样式),没错,那也是我做的。
裁员前一天,我跟经理做了最后一次 1 on 1。她还告诉我:我在团队里的表现挺不错。
结果第二天早上,我们整个团队就没了。
我想,表现和运气并不总能相交。
My God, In God We Trust
But we never really know what got discussed
Click boom! Then it happened
But no one else was in the room where it happened