我用 Rust 重寫了一個 Java 微服務,然后丟了工作
一出關于“選了不合時宜的技術”的黑色喜劇。
周一我還有工牌。
周二我的工牌成了杯墊。
罪名?我把一個叫 “Billing-Quotes” 的、波瀾不驚的 Java 微服務(13 個上游)用 Rust 重寫了。p95 更瘦了、CPU 更冷靜、內存更低,基礎設施賬單開始像小冰箱數字那樣往下掉。然后 CTO 叫我帶個箱子來。
這是一份技術正確、政治錯誤、文化核污染的事后剖析。
如果你也曾在凌晨兩點盯著 JVM 火焰圖,幻想著交付一個干凈利落的 Rust 單一二進制——這就是你的帶人頭數的愛情喜劇。
現場:看上去“有罪”的服務
- 患者:Spring Boot 3.x,Java 21;雙副本;每個 2 vCPU / 4 GB RAM
- SLO:p95 < 120 ms;可用性四個 9(和我健身卡一樣“立志”)
- 流量:午間尖峰——批量刷新 + 用戶像“打了濃縮咖啡的啄木鳥”一樣猛點 Get Quote
- 性能異味:JSON 瞬時高峰引發 GC 打嗝;“DTO 的 DTO”善意設計把分配量吹脹
- 額外阻力:一個“為一致性”而觸一切的網關跳轉;以及負責鑒權、指標、零食(?) 的 sidecar
不是不能跑——只是穿著羽絨服去健身。
癢點:為什么伸手去拿 Rust
三個信號在喊“上系統語言”:
- 高扇出 I/O:內部 gRPC + 話多的支付適配器
- 炙熱 JSON 路徑:每一次多余分配都會折返到 p99 身上
- 尾延遲比吞吐更重要:長尾在咬收入
我搞了個 spike:Axum、Tokio、serde、reqwest(gRPC 用 tonic)、sqlx 接 Postgres、tracing + OpenTelemetry。 鏡像了每個 endpoint 與錯誤契約,像博物館藏品一樣保留了 header,用可灰度的 strangler 做殼,從 1% → 10% → 50% → 100% 切,不驚動 Security。
兩周金絲雀,同樣的流量結構:
- p95:118 ms → 94 ms(穩)
- p99:由刺兒變順滑(短且少的尖 spikes)
- 峰值 CPU / RPS:降約 30%
- 穩態內存:降約 45%
- 基礎設施賬單:個位數百分比下降(不是電影橋段,但 CFO 會笑)
- 啟動時間“眨眼即緒”,產物小巧,儀表盤無聊到剛剛好
我有圖表。我有 README。我有笑容。很快,我沒有工作。
那場讓我“丟劇情”的評審會
開頭是樂觀的:
- SRE:“數字很好看。”
- DevOps:“二進制體量可愛。”
- 經理:“值班輪換能接住嗎?”
- 安全:“威脅建模在哪兒?”
- CTO:“我們對語言蔓延(language creep)的政策是什么?”
語言蔓延。我追的是毫秒;他們擔的是治理——讓公司可預測的安靜膠水。
眉頭的潛臺詞:
- 值班素養:我們的 Playbook 是 JVM 型:JFR、heap dump、熟悉的告警。Rust 需要新肌肉。
- 招聘與覆蓋:凌晨三點,誰能安全下手?我們的板凳深度在 Java。
- 安全流水線:SBOM、SAST、許可證校驗——全為 JVM 調了味。Rust 很棒,我們的鏈路沒準備好。
- 平臺一致性:千百個局部勝利,扛不住一個組織級異類。
- 變更周期:我們削了延遲,卻加了幾周的跨團隊工作。
我的技術勝利,成了社會性退步。我把尾巴收好了,卻把地圖炸了。
四個把“升職”寫成“離場”的錯誤
1) 優化了錯誤的 KPI
死盯 p95,領導層在乎交付速度與人員跨服務機動性。我的圖沒動他們的圖。
2) 低估了“平均解釋時間”
復盤靠共享語言與共享工具。我在一句話中途,引入了新方言。
3) 把工具鏈債務當“以后再說”
工程師把 toil 當謎題;組織把 toil 當風險。我的謎題,是他們的呼叫器。
4) 把“更快更省更穩”誤以為“更可預測”
用新語言重寫一個服務,是穿著“局部重構”的外衣在宣布一項戰略。
Rust 到底改變了什么(和沒改變什么)
真的改變了:
- 堆內戲碼 → 所有權清晰:炙熱的 JSON 路徑不再像肥皂劇一樣分配。
- 尾延遲:更少的 GC 方差;更少“p99 在尖叫”的時刻。
- 啟動與空轉足跡:冷啟動與scale-to-zero 的游戲更輕松。
沒改變(抱歉):
- 數據庫:如果你的瓶頸是 Java 里的 Postgres,換 Rust 后它還是 Postgres——只是生命周期干凈了。
- 跨團隊牽引:新棧 → 新工具 → 新人要訓練。
- 功能上線速度:如果是產品邏輯占大頭,語言速度不等于出貨速度。
好笑的部分
財務剛發來賬單變好的喜訊,安全就問誰批準了新 SBOM 流水線。 PM 問這會不會影響 Q4 促銷。 SRE 問 eBPF 鬧脾氣時怎么 on-box 調試。 CTO 問還有多少服務會“受益于 Rust”。
實話實說:“大概一把手,五個以內。” 他點頭:“我愛工藝,我不愛先例。”
事實證明:先例的分量,比二進制還重。 周五,我的工牌滴——紅了。
更好的路線圖(我本該這么干)
如果你對 Rust 手癢(有時值得),請按這套無聊但正確的順序來:
- 申請一條“運行時例外”通道一頁紙、一個季度、一個服務。準入標準:量化 SLO 痛點、可隔離的熱路徑、成熟庫、可回滾計劃、以及達不到就日落的條款。
- 先上 sidecar,不要重寫把一個熱路徑(序列化、加密、圖像處理)剝離成同機 Rust sidecar,Java 仍是老大。同儀表盤測尾部改善。
- 讓平臺團隊擁有工具鏈爭取小額立項:SBOM、SAST、簽名、追蹤規范、崩潰捕獲、儀表盤。平臺點了頭,你是公民,不是游擊。
- 把可觀測性當“契約”寫代碼前,先鎖定日志格式、Trace ID、錯誤分類、儀表盤。“看起來一樣,跑得更好”才是容易過會的敘事。
- Strangler + 業務級開關從一個 endpoint起步。用開關或 Envoy 路由前滾/回滾。回滾要以分鐘計,而不是開會計。
- Day 1 就發布“刪除計劃”能刪是實驗的靈魂。出生證明上就寫上訃告草稿。
沒行話的復盤
What Went Well(做得好)
- 金絲雀干凈、度量清晰、可逆切換
- 真實可復現的尾部改善
- 文檔解釋形態而不僅是語法
What Went Badly(做壞了)
- 性能壓過了可預測性
- 未融資的工具與培訓債
- 把治理當作“別人的 Jira”
Next Time(下次要這樣)
- 先 sidecar,后重寫(也許永不)
- 平臺擁有安全與 SBOM 后再落代碼
- 先要政策,不要在 PR 里偷帶戰略
一個袖珍 Go/No-Go 清單(拿走就用)
- SLO 痛點已量化且業務可見
- 熱路徑可被開關隔離
- 平臺已買入:SBOM / SAST / 簽名 / 追蹤
- 值班素養:至少 4 人能在凌晨三點安全排障
- 分鐘級回滾
- 刪除計劃已批準
把它貼在鍵盤邊。對不齊就先去調 GC、修 N+1,把英雄披風留到萬圣節。






























