戰(zhàn):構(gòu)建可驗(yàn)證、可治理、可擴(kuò)展的分布式系統(tǒng))
最近在帶團(tuán)隊(duì)做一套訂單中臺改造從單體往分布式微服務(wù)遷移壓力最大的不是寫業(yè)務(wù)代碼而是控質(zhì)量、控變更、控邊界。恰好這幾個(gè)月我們把 Claude Code 深度接進(jìn)了日常研發(fā)流程用它輔助設(shè)計(jì)、編碼、補(bǔ)測試、寫遷移腳本跑完一輪下來我最大的感受是這工具能不能發(fā)揮價(jià)值完全取決于你把它放在什么位置、用什么規(guī)則約束它。把它當(dāng)“自動補(bǔ)全”你得到的只是零散代碼片段把它當(dāng)成一個(gè)“能寫代碼的架構(gòu)師實(shí)習(xí)生”并且配好驗(yàn)證、治理、擴(kuò)展的整套規(guī)則它能實(shí)打?qū)嵉貛湍憬桓渡a(chǎn)級系統(tǒng)。這篇博文我想整理的就是這套用法如何用 Claude Code 構(gòu)建一個(gè)可驗(yàn)證、可治理、可擴(kuò)展的生產(chǎn)級分布式系統(tǒng)。內(nèi)容會覆蓋環(huán)境配置、驗(yàn)證策略、代碼治理、架構(gòu)擴(kuò)展以及一套可以直接復(fù)制的實(shí)操流程。不管是剛接觸 Claude Code 的后端工程師還是想在團(tuán)隊(duì)里推 AI 輔助開發(fā)的技術(shù)負(fù)責(zé)人都能從中拿到能落地的方案。1. 先搞清楚目標(biāo)可驗(yàn)證、可治理、可擴(kuò)展到底意味著什么1.1 三個(gè)關(guān)鍵詞不是擺設(shè)是生產(chǎn)系統(tǒng)的生死線“可驗(yàn)證、可治理、可擴(kuò)展”這三個(gè)詞平時(shí)在技術(shù)方案里見得很多但真落到分布式系統(tǒng)上每一環(huán)都有非常具體的指向??沈?yàn)證說的是你交付出去的每一個(gè)服務(wù)、每一次改動都能通過自動化手段證明它是對的。不是“本地跑通了”而是單元測試、契約測試、集成測試、端到端驗(yàn)證全部能過數(shù)據(jù)變更能回滾接口改動能被契約約束住。分布式系統(tǒng)里服務(wù)之間的調(diào)用鏈拉得很長A 服務(wù)改了接口B 服務(wù)可能到上線那天才知道壞了。沒有驗(yàn)證體系改代碼就是在踩地雷。可治理說的是團(tuán)隊(duì)多人協(xié)作時(shí)AI 生成的代碼不是失控的。誰在什么時(shí)候改了哪塊邏輯、用了什么模型、跑了哪些命令全部有日志、有權(quán)限控制、有審查機(jī)制。這一點(diǎn)最容易被人忽視尤其是個(gè)人開發(fā)者用 Claude Code 的時(shí)候感覺“它能直接改文件太爽了”但在生產(chǎn)系統(tǒng)里這種權(quán)限裸奔狀態(tài)就是事故的溫床??蓴U(kuò)展說的是系統(tǒng)的架構(gòu)演進(jìn)能跟上業(yè)務(wù)增長。今天你是 2 個(gè)服務(wù)的單體集群明天可能是 20 個(gè)微服務(wù)后天可能是跨地域多活。用 Claude Code 寫出來的代碼如果一開始就是貼死業(yè)務(wù)邏輯的“面條代碼”那擴(kuò)展的時(shí)候不是改代碼是推翻重來。1.2 Claude Code 在分布式系統(tǒng)建設(shè)中扮演什么角色我的定位是它是“結(jié)對程序員 代碼審查助手 運(yùn)維腳本生成器”三合一但它不是架構(gòu)師。架構(gòu)方向的決策必須由人來做Claude Code 負(fù)責(zé)的是把決策落實(shí)到代碼層面并且?guī)湍惆雅K活累活干了。舉個(gè)例子我讓它幫我生成一個(gè)分布式限流組件它能在幾分鐘內(nèi)給你一個(gè)包含令牌桶算法、Redis 存儲、Spring AOP 接入的完整模塊單元測試都給你寫好。但如果我問它“我們到底應(yīng)該用 Redis 分布式鎖還是 ZooKeeper 鎖”它能給出的只是泛泛的優(yōu)劣勢對比真正拍板還得靠你自己對業(yè)務(wù)場景的理解。所以我的團(tuán)隊(duì)里立了一條規(guī)矩Claude Code 輸出的所有架構(gòu)設(shè)計(jì)類內(nèi)容必須經(jīng)過一名高級工程師人工審查后才允許進(jìn)入代碼庫。這不是不信任工具而是對生產(chǎn)系統(tǒng)的敬畏。1.3 我搭建這套體系前的配置基線在進(jìn)入具體章節(jié)之前先把我這邊的基礎(chǔ)環(huán)境交代一下后面講的所有操作都是基于這套環(huán)境Claude Code 版本持續(xù)保持最新版npm 全局安裝執(zhí)行方式macOS 本地終端 CI 服務(wù)器GitHub Actions遠(yuǎn)程執(zhí)行集成工具VS Code 插件 MCPModel Context Protocol連接 MySQL、Redis、Kafka權(quán)限模式默認(rèn)非自動執(zhí)行所有寫文件/執(zhí)行命令操作需人工確認(rèn)會話管理按項(xiàng)目隔離每個(gè)服務(wù)一個(gè)獨(dú)立工作區(qū)這套配置的核心思路是Claude Code 有很強(qiáng)的能力但我要把它關(guān)在“籠子”里使用。讓它能看見完整的項(xiàng)目上下文能提出方案、寫代碼、跑測試但所有副作用操作都要經(jīng)過確認(rèn)和記錄后面會展開講。2. 環(huán)境準(zhǔn)備與基礎(chǔ)配置把地基打牢再開工2.1 安裝與初始化的完整步驟Claude Code 的安裝非常簡單一條 npm 命令搞定前提是你的機(jī)器上已經(jīng)有 Node.js 18 環(huán)境npm install -g anthropic-ai/claude-code安裝完成后在終端輸入claude進(jìn)入交互式界面首次使用會引導(dǎo)你完成認(rèn)證登錄。這里要說一個(gè)我踩過的坑如果你在公司內(nèi)網(wǎng)環(huán)境或者網(wǎng)絡(luò)代理設(shè)置比較復(fù)雜登錄環(huán)節(jié)容易卡住甚至報(bào) 403。我遇到過幾次排查下來基本都是代理環(huán)境變量導(dǎo)致的 SSL 握手問題解決辦法是清理環(huán)境變量或者確認(rèn)代理對 Anthropic 域名的訪問策略。認(rèn)證完成之后我強(qiáng)烈建議你做的第一件事不是開始寫代碼而是運(yùn)行claude config set -g theme dark claude config set -g verbose false把界面和日志先調(diào)整到適合長期工作的狀態(tài)。默認(rèn)配置下日志很啰嗦會刷掉你的注意力。2.2 在 VS Code 里集成 Claude Code很多人習(xí)慣在 IDE 里使用 AI 工具Claude Code 官方提供了 VS Code 插件安裝后可以在編輯器側(cè)邊欄直接打開會話面板。安裝方式有兩種在 VS Code 擴(kuò)展市場搜索 “Claude Code” 直接安裝如果你已經(jīng)在終端里安裝過 Claude Code擴(kuò)展會自動識別到本機(jī)的 Claude Code 可執(zhí)行文件這里有一個(gè)重要配置插件默認(rèn)會繼承終端里的認(rèn)證狀態(tài)但如果你的終端用的是 zsh 而 VS Code 里跑的是默認(rèn) shell可能出現(xiàn)“找不到 claude 命令”的問題。需要在 VS Code 的 settings.json 里指定 claude 的絕對路徑比如{ claude-code.path: /usr/local/bin/claude }路徑可以用which claude查出來。2.3 CLAUDE.md讓 AI 讀懂你的項(xiàng)目規(guī)則Claude Code 最核心的配置是項(xiàng)目根目錄下的CLAUDE.md文件。這個(gè)文件相當(dāng)于給 AI 的“入職手冊”在每次會話開始時(shí)Claude Code 會自動讀取它作為理解項(xiàng)目、執(zhí)行任務(wù)的背景知識。我的團(tuán)隊(duì)里每個(gè)服務(wù)倉庫的CLAUDE.md都會包含以下幾塊內(nèi)容你可以直接參照這個(gè)結(jié)構(gòu)寫# 項(xiàng)目名稱 一句話描述項(xiàng)目定位如訂單中臺 - 核心交易服務(wù) ## 技術(shù)棧 - 語言/框架Java 17 Spring Boot 3.2 - 存儲MySQL 8.0主庫/ Redis 7緩存 - 消息Kafka 3.x - 部署Docker Kubernetes ## 項(xiàng)目結(jié)構(gòu) - 模塊劃分controller / service / repository / domain / infrastructure - 分層規(guī)則controller 層不允許寫業(yè)務(wù)邏輯repository 層不允許出現(xiàn)業(yè)務(wù)判斷 ## 編碼規(guī)范 - 所有對外接口必須返回統(tǒng)一響應(yīng)體 ResultT - 所有金額字段必須用 BigDecimal禁止用 Double - 創(chuàng)建/更新時(shí)間統(tǒng)一用 Long 類型毫秒時(shí)間戳 ## 測試要求 - 每個(gè) service 方法必須有對應(yīng)單元測試 - 對外接口變更必須同步更新契約測試文件 - 本地跑全量測試命令./mvnw verify ## 禁止事項(xiàng) - 不要修改 pom.xml 的依賴版本除非明確要求 - 不要直接操作生產(chǎn)數(shù)據(jù)庫所有變更走遷移腳本 - 不要在 service 里直接 new 線程池必須使用項(xiàng)目統(tǒng)一線程池組件這個(gè)文件的作用非常大。沒有它的時(shí)候Claude Code 生成的代碼每一份都“似曾相識但又不完全對”有它之后生成的代碼里 80% 的規(guī)范問題直接消失。我甚至建議給全局加一個(gè)~/.claude/CLAUDE.md把你個(gè)人的通用編碼偏好寫進(jìn)去這樣不管開哪個(gè)項(xiàng)目AI 都會默認(rèn)遵守你的習(xí)慣。2.4 權(quán)限控制別讓 AI 裸奔Claude Code 默認(rèn)在執(zhí)行寫文件、運(yùn)行命令等操作時(shí)會向你請求確認(rèn)但在某些模式下比如--dangerously-skip-permissions它會跳過所有確認(rèn)這個(gè)模式我在生產(chǎn)環(huán)境里是絕對禁用的。我這邊推薦的做法是在啟動會話時(shí)就明確權(quán)限邊界claude --allowedTools Read,Edit,Write,Bash(npm test:*) --disallowedTools Bash(git push),Bash(rm -rf)上面的命令允許 Claude Code 讀文件、編輯文件、運(yùn)行測試命令但禁止執(zhí)行g(shù)it push和危險(xiǎn)的刪除命令。你可以根據(jù)實(shí)際場景調(diào)整允許/禁止的工具列表我的原則是能讓它干活的權(quán)限要給但會給生產(chǎn)環(huán)境造成不可逆影響的操作一律禁止自動執(zhí)行。權(quán)限配置的關(guān)鍵參數(shù)我整理成了表格方便你對照使用配置項(xiàng)作用推薦設(shè)置--allowedTools允許自動執(zhí)行的操作白名單按需授權(quán)只給當(dāng)前任務(wù)需要的--disallowedTools禁止執(zhí)行的操作黑名單加入高危命令如git push --force、生產(chǎn)環(huán)境刪除操作--permission-mode權(quán)限模式默認(rèn)確認(rèn)模式禁用dangerously-skip-permissions--model指定使用的模型根據(jù)任務(wù)復(fù)雜度選擇簡單任務(wù)用小模型省錢--max-turns單次會話最大輪數(shù)防止死循環(huán)消耗配額2.5 用 MCP 打通數(shù)據(jù)源讓 AI 能“看見”數(shù)據(jù)庫Claude Code 的上下文窗口再大也不可能預(yù)知你的業(yè)務(wù)數(shù)據(jù)長什么樣。所以我們要用 MCP 把開發(fā)環(huán)境的數(shù)據(jù)庫、消息隊(duì)列、緩存等基礎(chǔ)設(shè)施“接入”到 AI 的視野里。MCP 的配置也是寫在CLAUDE.md或者單獨(dú)的配置文件里我舉個(gè)例子連接 MySQL 的配置片段## MCP Servers - mysql: 通過 mysql-mcp-server 連接schema 信息自動同步 命令: npx mysql-mcp-server --host 127.0.0.1 --port 3306 --user dev --password dev123配置好之后你可以直接對 Claude Code 說“幫我查一下訂單表結(jié)構(gòu)找出所有金額字段”它能通過 MCP 直接查庫并返回結(jié)果這比貼建表語句給它是完全不同的體驗(yàn)。但這里有一個(gè)重要提醒在生產(chǎn)環(huán)境千萬不要給 MCP 配寫權(quán)限只讓它讀 schema、讀數(shù)據(jù)用于理解業(yè)務(wù)任何寫操作必須走人工確認(rèn)或遷移腳本。3. 可驗(yàn)證性如何確保 AI 寫出來的代碼真的能上線3.1 AI 生成代碼最大的風(fēng)險(xiǎn)不是“寫錯(cuò)”而是“看起來對”我發(fā)現(xiàn)很多團(tuán)隊(duì)不敢用 AI 寫生產(chǎn)代碼核心原因不是模型能力不行而是 AI 生成代碼有一種迷惑性——它語法正確、結(jié)構(gòu)完整、甚至注釋都寫好了但業(yè)務(wù)邏輯可能完全是錯(cuò)的。舉一個(gè)我實(shí)際遇到的例子。讓 Claude Code 實(shí)現(xiàn)一個(gè)“訂單超時(shí)自動關(guān)閉”功能它很自然地寫出了一個(gè)定時(shí)任務(wù)每五分鐘掃描一次訂單表把超過三十分鐘未支付的訂單置為關(guān)閉狀態(tài)。單看代碼邏輯完全沒問題。但懂業(yè)務(wù)的人一眼就能看出問題這個(gè)方案在分布式環(huán)境下是錯(cuò)的。如果系統(tǒng)部署了多個(gè)實(shí)例定時(shí)任務(wù)會在每個(gè)實(shí)例上同時(shí)跑不做分布式鎖就會產(chǎn)生重復(fù)掃描、重復(fù)更新甚至并發(fā)扣減庫存的嚴(yán)重事故。這就是 AI 編碼的陷阱它擅長生成“符合常規(guī)模式的代碼”但不理解你系統(tǒng)的特殊約束。解法只有一個(gè)——把所有關(guān)鍵行為的驗(yàn)證閉環(huán)前置到開發(fā)流程里用測試、契約、檢查機(jī)制把錯(cuò)誤擋在上線之前。3.2 三層驗(yàn)證架構(gòu)單測、契約、端到端我這邊把驗(yàn)證分成三層每一層對應(yīng)不同粒度的保障第一層是單元測試覆蓋最小業(yè)務(wù)單元的輸入輸出和邊界條件。這一層最容易讓 Claude Code 自動生成但也是我審查最嚴(yán)格的一層。我會要求它對每個(gè) service 方法生成測試包括正常路徑、異常路徑、邊界值、并發(fā)場景生成完再讓人工抽查。第二層是契約測試這是分布式系統(tǒng)的關(guān)鍵護(hù)城河。服務(wù)之間通過 HTTP 或消息通信接口的請求響應(yīng)結(jié)構(gòu)一旦變化下游服務(wù)立刻遭殃。我們用 Pact 或者 Spring Cloud Contract 做消費(fèi)者驅(qū)動的契約測試把每個(gè)服務(wù)的對外接口規(guī)范固化成文件任何一方改動契約CI 就會報(bào)錯(cuò)逼著雙方協(xié)商兼容方案。第三層是端到端測試用 Testcontainers 起一套完整的依賴環(huán)境MySQL、Redis、Kafka模擬真實(shí)業(yè)務(wù)鏈路跑通核心流程。這一層不是為了測每一個(gè)細(xì)節(jié)而是驗(yàn)證系統(tǒng)級的行為符合預(yù)期比如“下單 → 扣庫存 → 發(fā)消息 → 訂單狀態(tài)變更”這條主鏈路。這三層驗(yàn)證跑下來我才能放心地把 Claude Code 生成的代碼合入主干分支。3.3 讓 Claude Code 先生成測試再生成實(shí)現(xiàn)操作上有一個(gè)非常有效的小技巧不要讓它直接寫實(shí)現(xiàn)代碼而是先讓它寫測試。我的做法是這樣的拿一個(gè)“用戶積分變更”的需求舉例我在會話里敲入請為 UserScoreService.changeScore(Long userId, int delta) 方法編寫單元測試。 業(yè)務(wù)規(guī)則 1. 積分為負(fù)數(shù)時(shí)拋 IllegalArgumentException 2. 用戶不存在時(shí)拋 UserNotFoundException 3. 變更后的積分不能小于 0 請先寫測試再根據(jù)測試反推實(shí)現(xiàn)。這么說的好處是Claude Code 會先基于業(yè)務(wù)規(guī)則定義預(yù)期行為然后為了通過測試去寫實(shí)現(xiàn)代碼。這樣生成的代碼天然帶著“驗(yàn)證基因”而不是天馬行空地自由發(fā)揮。我實(shí)測下來用這種方式生成的代碼review 時(shí)發(fā)現(xiàn)的邏輯錯(cuò)誤數(shù)量明顯減少。3.4 把驗(yàn)證嵌入 CI/CDAI 生成的代碼也要過流水線Claude Code 不僅能幫你寫業(yè)務(wù)代碼還能幫你把這些驗(yàn)證流程集成到 CI 流水線里。我讓它在 GitHub Actions 里自動生成了一套工作流核心階段如下name: verify on: [push, pull_request] jobs: test: runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: test ports: [3306:3306] steps: - uses: actions/checkoutv4 - name: Run unit tests run: ./mvnw test - name: Run contract tests run: ./mvnw verify -Pcontract-tests - name: Run end-to-end tests run: ./mvnw verify -Pe2e-tests每一個(gè) PR 進(jìn)來這套流水線都會完整跑一遍三層驗(yàn)證任何一層失敗都不允許合并。這樣做還有一個(gè)好處Claude Code 提出了一些方案改動時(shí)它會先看 CI 跑不跑得過而不是只拿“本地編譯過了”當(dāng)理由。這是可驗(yàn)證性的最終保證。4. 可治理性多人協(xié)作下如何管住 AI 的“手”4.1 治理的核心可追溯、可審計(jì)、可控回滾當(dāng)團(tuán)隊(duì)里每個(gè)人都用 Claude Code 寫代碼時(shí)最大的問題不是代碼質(zhì)量問題而是失控問題。A 讓 AI 改了配置B 讓 AI 動了接口C 讓 AI 跑了數(shù)據(jù)庫遷移腳本——這些操作如果沒有記錄、沒有審批、沒有回滾通道系統(tǒng)遲早被自己人搞掛??勺匪菔钦f每一段由 AI 生成的改動都能追溯到對應(yīng)的需求和操作者。可審計(jì)是說每個(gè)關(guān)鍵動作都有日志留痕出了問題能復(fù)盤??煽鼗貪L是說任何 AI 做的變更都有對應(yīng)的回滾方案絕不出現(xiàn)“改壞了沒法回”的局面。4.2 規(guī)范先行把約束寫進(jìn) CLAUDE.md在多人協(xié)作的場景下CLAUDE.md不僅僅是給 AI 看的規(guī)范更是團(tuán)隊(duì)對 AI 的使用公約。除了前面提到的技術(shù)棧和結(jié)構(gòu)約束我們還加了一些治理?xiàng)l款## AI 使用治理規(guī)則必須遵守 1. 任何涉及數(shù)據(jù)庫表結(jié)構(gòu)變更的操作必須先輸出遷移腳本并提交 DBA 審查 2. 修改對外接口簽名或請求響應(yīng)結(jié)構(gòu)時(shí)必須同步更新契約測試并通知下游負(fù)責(zé)人 3. 生成代碼時(shí)必須包含完整注釋注明業(yè)務(wù)背景和設(shè)計(jì)理由禁止只有“根據(jù)需求實(shí)現(xiàn)”這種無意義注釋 4. 禁止 AI 直接修改 Kubernetes 部署文件中的鏡像版本發(fā)布操作由運(yùn)維流水線統(tǒng)一處理 5. 所有 AI 會話的關(guān)鍵輸出保存到 docs/ai-sessions/ 目錄按日期命名這些條款不是限制 AI 的能力而是把不確定性壓縮到可控范圍。尤其第 5 條我會讓 Claude Code 在每次重要會話結(jié)束時(shí)自動把對話摘要、產(chǎn)出物、未決問題導(dǎo)出成 Markdown 文件這樣即使寫代碼的人休假了后來的人打開目錄就能看到那次改動的完整背景。4.3 代碼審查時(shí)AI 生成代碼的特殊審查點(diǎn)傳統(tǒng)的人工代碼審查關(guān)注的是業(yè)務(wù)邏輯正確性、代碼風(fēng)格、性能問題。但審查 AI 生成的代碼我額外加了幾個(gè)檢查項(xiàng)這里整理成表格審查維度檢查點(diǎn)原因真實(shí)性依賴的包、API 是否存在版本號是否真實(shí)AI 會“發(fā)明”不存在的庫尤其是小眾工具庫安全性是否有硬編碼密鑰、SQL 注入、越權(quán)風(fēng)險(xiǎn)AI 默認(rèn)生成“能跑”的代碼不默認(rèn)安全的代碼業(yè)務(wù)匹配是否理解項(xiàng)目特有的業(yè)務(wù)規(guī)則和約束容易生成通用方案忽略你系統(tǒng)的特殊性邊界處理超時(shí)、重試、熔斷等容錯(cuò)邏輯是否完整分布式系統(tǒng)里這些比業(yè)務(wù)主流程更重要性能隱患是否存在 N1 查詢、循環(huán)調(diào)用 RPC、大事務(wù)AI 容易生成代碼正確但性能災(zāi)難的寫法我一般要求團(tuán)隊(duì)里每個(gè)人在 review AI 生成代碼時(shí)按這個(gè)表格逐項(xiàng)過一遍而不是像以前那樣憑感覺掃一眼就點(diǎn)通過。這套做法推行之后我們合并到主干的 AI 生成代碼線上問題率降了一個(gè)數(shù)量級。4.4 審計(jì)日志Claude Code 自己的“黑匣子”Claude Code 默認(rèn)會在會話中進(jìn)行詳細(xì)的操作記錄包括每次調(diào)用模型的輸入輸出、執(zhí)行過的命令、修改過的文件。但在多人協(xié)作環(huán)境下默認(rèn)的日志放在各自本地沒法統(tǒng)一審計(jì)。我們的做法是給開發(fā)者統(tǒng)一配置日志輸出目錄并通過 CI 流程收集會話記錄。具體的配置方式是在啟動 Claude Code 時(shí)指定日志路徑claude --session-log-path ~/.claude/logs然后在 CI 中加入一步掃描這些日志文件并上傳到團(tuán)隊(duì)內(nèi)部的存儲。這樣做的好處是當(dāng)你發(fā)現(xiàn)某段生產(chǎn)代碼有問題時(shí)可以立刻反查是在哪個(gè)會話里被生成的、當(dāng)時(shí)的上下文是什么、有沒有執(zhí)行過額外操作這比“開發(fā)者回憶”靠譜得多。4.5 發(fā)布管控AI 生成的改動不能直接上生產(chǎn)最后一條治理紅線是發(fā)布管控。我定的規(guī)矩是Claude Code 生成或修改的代碼必須先通過常規(guī)的 PR 流程合并到主干分支再通過 CI 流水線完成部署。任何“讓 AI 直接改生產(chǎn)環(huán)境”的行為在我的團(tuán)隊(duì)里都屬于嚴(yán)重違規(guī)。有些人可能會覺得這太保守了AI 改產(chǎn)線腳本更快。但對生產(chǎn)系統(tǒng)來說快不是第一位的穩(wěn)才是。我寧可在治理流程上多花十分鐘也不愿在生產(chǎn)事故后花十個(gè)小時(shí)復(fù)盤。這個(gè)原則同樣適用于你個(gè)人的項(xiàng)目哪怕只有你自己一個(gè)開發(fā)者也應(yīng)該走完整的發(fā)布鏈路這是職業(yè)習(xí)慣問題。5. 可擴(kuò)展性從架構(gòu)設(shè)計(jì)到代碼落地讓系統(tǒng)能跟著業(yè)務(wù)一起長大5.1 擴(kuò)展性不是事后補(bǔ)的是設(shè)計(jì)出來的一個(gè)分布式系統(tǒng)能不能輕松擴(kuò)容不取決于你最后用了多少臺機(jī)器而取決于你寫前幾個(gè)服務(wù)時(shí)怎么設(shè)計(jì)的。如果服務(wù)之間有隱式的共享數(shù)據(jù)庫、繞過 API 直接訪問其他服務(wù)的表、或者把有狀態(tài)數(shù)據(jù)都放在本地內(nèi)存里那系統(tǒng)的擴(kuò)展天花板在你設(shè)計(jì)的第一天就注定了。用 Claude Code 輔助開發(fā)時(shí)我會在項(xiàng)目啟動前就讓它輸出一份“擴(kuò)展性設(shè)計(jì)檢查清單”把它作為后續(xù)所有代碼生成的約束條件。這份檢查清單包括服務(wù)是否做到無狀態(tài)化Session 是否外移到 Redis服務(wù)之間的調(diào)用是否全部通過 API 網(wǎng)關(guān)適配沒有直接暴露內(nèi)部服務(wù)地址數(shù)據(jù)庫層面是否有分庫分表預(yù)案當(dāng)前表結(jié)構(gòu)是否預(yù)留了分片鍵核心鏈路是否使用消息隊(duì)列解耦還是寫死了同步調(diào)用所有第三方依賴是否有超時(shí)、重試、熔斷配置這份清單一旦定下來就在CLAUDE.md里固化成規(guī)范Claude Code 生成新服務(wù)時(shí)就會自動帶上這些考量。5.2 讓 Claude Code 幫你做架構(gòu)評審很多人不知道 Claude Code 還有一個(gè)很好用的場景架構(gòu)評審。在寫代碼之前我經(jīng)常把當(dāng)前系統(tǒng)的部署圖、核心接口定義、數(shù)據(jù)庫表結(jié)構(gòu)喂給 Claude Code然后讓它以“外部架構(gòu)師”的視角提建議。比如我說“我們目前訂單服務(wù)訪問數(shù)據(jù)庫耗時(shí)較高并發(fā)量上來了之后接口響應(yīng)變得越來越慢請幫忙分析可能原因并給出優(yōu)化建議。”它會輸出一版結(jié)構(gòu)化分析包含索引問題、連接池配置、緩存缺失、慢查詢等多個(gè)維度并且給出對應(yīng)的代碼改動建議。但這里我要潑一盆冷水AI 的架構(gòu)建議只能作為參考不能作為決策依據(jù)。它沒有你系統(tǒng)的全量指標(biāo)看不到真實(shí)的鏈路追蹤更不了解團(tuán)隊(duì)的維護(hù)能力。我會把它的輸出當(dāng)成一份“待驗(yàn)證的候選方案列表”挑出有道理的方案再人工驗(yàn)證而不是拿過來就用。5.3 用 AI 生成可復(fù)用的分布式基礎(chǔ)組件分布式系統(tǒng)里有很多重復(fù)造輪子的基礎(chǔ)組件分布式鎖、分布式 ID 生成器、限流器、鏈路追蹤工具類、統(tǒng)一異常處理。這些組件的特點(diǎn)是模式固定、邏輯相對通用非常適合讓 Claude Code 生成初版再由團(tuán)隊(duì)里的高級工程師審查打磨。舉一個(gè)實(shí)際例子我讓 Claude Code 生成一個(gè)基于 Redis 的分布式鎖工具類它給出的核心實(shí)現(xiàn)包含public class RedisDistributedLock { private final StringRedisTemplate redisTemplate; public boolean tryLock(String lockKey, String requestId, long expireSeconds) { Boolean result redisTemplate.opsForValue() .setIfAbsent(lockKey, requestId, Duration.ofSeconds(expireSeconds)); return Boolean.TRUE.equals(result); } public boolean releaseLock(String lockKey, String requestId) { String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; Long result redisTemplate.execute( new DefaultRedisScript(script, Long.class), Collections.singletonList(lockKey), requestId ); return Long.valueOf(1L).equals(result); } }這段代碼的亮點(diǎn)是釋放鎖的時(shí)候用了 Lua 腳本保證原子性并且校驗(yàn)了持有者身份避免了誤刪別人的鎖。這些細(xì)節(jié)如果靠人從零寫可能也能寫出來但 AI 在幾分鐘內(nèi)給出一個(gè)可用的初版效率提升是實(shí)打?qū)嵉摹?.4 規(guī)范生成模塊化代碼避免“一鍋粥”可擴(kuò)展性的敵人永遠(yuǎn)是不合理的耦合。我見過太多系統(tǒng)一開始是一個(gè)大單體后來拆微服務(wù)的時(shí)候發(fā)現(xiàn)業(yè)務(wù)邏輯糾纏在一起根本切不開。Claude Code 寫代碼時(shí)如果沒有任何約束它會傾向于把所有相關(guān)邏輯放在最方便的位置很快形成“上帝類”和循環(huán)依賴。我用的辦法是在項(xiàng)目的CLAUDE.md里明確規(guī)定模塊邊界和依賴規(guī)則。比如訂單服務(wù)的代碼生成規(guī)則## 模塊依賴規(guī)則 - domain 模塊純業(yè)務(wù)實(shí)體與業(yè)務(wù)規(guī)則不依賴任何框架和其他模塊 - application 模塊用例編排依賴 domain 模塊 - infrastructure 模塊數(shù)據(jù)庫、消息、外部接口實(shí)現(xiàn)依賴 domain 模塊接口禁止反向依賴 - controller 模塊HTTP 層適配依賴 application 模塊這樣規(guī)定之后Claude Code 生成新代碼時(shí)就會自動放到合理的位置不會出現(xiàn) controller 里寫 SQL 這種低級問題。模塊邊界清晰了未來系統(tǒng)的每個(gè)服務(wù)才能獨(dú)立演進(jìn)、獨(dú)立擴(kuò)縮容。5.5 緩存、消息隊(duì)列與數(shù)據(jù)庫擴(kuò)展的 AI 輔助分布式系統(tǒng)擴(kuò)容時(shí)最先遇到的瓶頸往往是存儲和流量。我可以讓 Claude Code 幫我做以下幾類擴(kuò)展準(zhǔn)備緩存擴(kuò)展方面讓它分析現(xiàn)有接口的緩存策略標(biāo)出哪些接口缺少緩存穿透、擊穿、雪崩的保護(hù)然后生成對應(yīng)的更新代碼。消息隊(duì)列擴(kuò)展方面讓它根據(jù)業(yè)務(wù)事件設(shè)計(jì) Topic 劃分方案生成生產(chǎn)者、消費(fèi)者的骨架代碼并配置好重試和死信隊(duì)列。數(shù)據(jù)庫擴(kuò)展方面讓它分析大表和慢查詢生成索引優(yōu)化建議和分庫分表預(yù)研代碼。這些操作我不建議一次性全部交給 AI 自動完成而是每完成一項(xiàng)就進(jìn)行人工 review 和測試。擴(kuò)展性建設(shè)是一個(gè)持續(xù)演進(jìn)的過程不是一錘子買賣。把它拆成一個(gè)個(gè)小任務(wù)夾在迭代里做反而比“下一版大重構(gòu)”更容易落地。6. 實(shí)操全流程從零到一構(gòu)建一個(gè)生產(chǎn)級分布式服務(wù)6.1 場景設(shè)定搭建“積分服務(wù)”并接入主系統(tǒng)為了讓整個(gè)流程更直觀我拿一個(gè)具體的例子演示完整操作。假設(shè)業(yè)務(wù)上需要一個(gè)獨(dú)立的積分服務(wù)包含積分發(fā)放、積分查詢、積分過期回收三個(gè)核心能力并且需要支持后續(xù)并發(fā)量翻倍后的水平擴(kuò)展。我的第一步操作是在會話里給 Claude Code 清晰的需求描述并且告訴它我們既有的技術(shù)規(guī)范和約束。描述越具體產(chǎn)出越可控。請?jiān)?services/points-service 下創(chuàng)建積分服務(wù)模塊。 功能需求 1. 提供積分發(fā)放接口內(nèi)部調(diào)用increasePoints 2. 提供積分查詢接口getUserPoints 3. 提供積分過期回收的定時(shí)任務(wù)按過期時(shí)間批量關(guān)閉過期積分 技術(shù)約束 - Java 17 Spring Boot 3.2 - 數(shù)據(jù)庫 MySQL表結(jié)構(gòu)按領(lǐng)域模型設(shè)計(jì)須包含樂觀鎖版本號字段 - 對外接口走公司統(tǒng)一 API 網(wǎng)關(guān)協(xié)議 - 所有金額/積分字段采用 Long 存儲單位個(gè) - 模塊結(jié)構(gòu)遵循項(xiàng)目已有分層規(guī)范 - 編寫完整單元測試6.2 查看 Claude Code 的產(chǎn)出物結(jié)構(gòu)收到需求后Claude Code 會在工作區(qū)里創(chuàng)建對應(yīng)的目錄結(jié)構(gòu)。一次典型生成出來的骨架大概是這樣的services/points-service/ ├── pom.xml ├── src/main/java/com/example/points/ │ ├── PointsServiceApplication.java │ ├── controller/PointsController.java │ ├── application/PointsApplicationService.java │ ├── domain/model/PointsAccount.java │ ├── domain/model/PointsRecord.java │ ├── domain/repository/PointsRepository.java │ ├── domain/service/PointsExpiryCalculator.java │ └── infrastructure/ │ ├── persistence/PointsRepositoryImpl.java │ ├── message/PointsEventPublisher.java │ └── config/PointsDataSourceConfig.java ├── src/main/resources/ │ ├── application.yml │ └── db/migration/V1__create_points_tables.sql └── src/test/java/com/example/points/ ├── domain/PointsExpiryCalculatorTest.java └── application/PointsApplicationServiceTest.java這個(gè)結(jié)構(gòu)已經(jīng)基本符合我們團(tuán)隊(duì)的分層規(guī)范了。遷移腳本、配置、測試一股腦兒生成好我只需要逐項(xiàng)審查確認(rèn)。整個(gè)過程從零點(diǎn)開始到初步可跑狀態(tài)不會超過十分鐘這在以前至少是半天的工作量。6.3 關(guān)鍵代碼實(shí)現(xiàn)的審查與修正當(dāng)然生成的代碼不能無腦接受。我以積分過期回收的定時(shí)任務(wù)為例展示一下審查時(shí)需要注意的細(xì)節(jié)。Claude Code 生成的初版可能是基于Scheduled(cron 0 */5 * * * ?)的本地定時(shí)任務(wù)邏輯上也能跑。但放到分布式環(huán)境里需要保證多實(shí)例部署時(shí)不重復(fù)執(zhí)行。所以我在 review 時(shí)會要求它改成基于 Redis 分布式鎖的方案并且增加“每次掃描分頁處理、單條處理失敗不影響批次整體”的容錯(cuò)邏輯。我會在會話里直接提出修改意見當(dāng)前實(shí)現(xiàn)存在兩個(gè)問題 1. 多實(shí)例部署時(shí)定時(shí)任務(wù)會重復(fù)執(zhí)行請加入 Redis 分布式鎖保護(hù) 2. 掃描邏輯需要分頁處理避免一次性加載全部過期記錄導(dǎo)致內(nèi)存溢出 請修改實(shí)現(xiàn)并補(bǔ)充對應(yīng)的單元測試。Claude Code 會基于反饋修改代碼這個(gè)過程我們稱之為“AI 代碼迭代循環(huán)”。一般經(jīng)過兩三輪這樣的修正生成的代碼就能達(dá)到上線標(biāo)準(zhǔn)。6.4 讓 AI 生成 Dockerfile 與 Kubernetes 部署清單生產(chǎn)系統(tǒng)的最后一步是部署。我同樣會讓 Claude Code 基于已有項(xiàng)目的部署模板為積分服務(wù)生成 Dockerfile 和 Kubernetes 配置。生成時(shí)它會自動帶上健康檢查、資源限制、優(yōu)雅停機(jī)等生產(chǎn)必備配置。Dockerfile 的關(guān)鍵內(nèi)容如下FROM maven:3.9-eclipse-temurin-17 AS builder COPY . /workspace WORKDIR /workspace RUN mvn clean package -DskipTests FROM eclipse-temurin:17-jre COPY --frombuilder /workspace/target/points-service.jar /app/app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, /app/app.jar]Kubernetes 部署文件里它也會自動加上livenessProbe和readinessProbe的配置保證實(shí)例在啟動完成前不會被流量打到在異常時(shí)能被自動重啟。這些細(xì)節(jié)對一個(gè)生產(chǎn)系統(tǒng)來說至關(guān)重要也不會被 AI 漏掉。6.5 運(yùn)行全鏈路驗(yàn)證并記錄會話在所有文件生成和修正完成之后我要求 Claude Code 跑一遍完整的驗(yàn)證命令鏈條編譯、單測、契約測試、構(gòu)建 Docker 鏡像然后把整次會話的關(guān)鍵決策摘要導(dǎo)出到docs/ai-sessions/2025-xx-xx-points-service.md作為后續(xù)審計(jì)和追溯的依據(jù)。這一步做完一個(gè)生產(chǎn)級分布式服務(wù)才算真正交付。從需求到上線過程中 AI 承擔(dān)了大約七成的編碼和配置工作剩下三成的人工工作集中在需求明確、方案決策、代碼審查和最終驗(yàn)證上。這個(gè)比例是我們在實(shí)踐中覺得比較舒服的配比——既能提升效率又能守住質(zhì)量底線。7. 常見問題與排查技巧實(shí)錄7.1 安裝失敗或登錄 403我自己和團(tuán)隊(duì)同事在安裝和登錄階段遇到的問題最多這里把典型現(xiàn)象和解決辦法整理出來現(xiàn)象可能原因解決辦法npm 安裝報(bào)權(quán)限錯(cuò)誤Node.js 安裝目錄權(quán)限不足用 nvm 管理 Node.js避免全局安裝權(quán)限問題登錄時(shí)瀏覽器回調(diào) 403代理環(huán)境變量干擾檢查HTTPS_PROXY等環(huán)境變量臨時(shí)清除后重試登錄半天跳轉(zhuǎn)不回來系統(tǒng)默認(rèn)瀏覽器兼容問題用claude login手動復(fù)制認(rèn)證鏈接到無痕窗口完成VS Code 插件找不到命令PATH 不一致在 settings.json 中顯式指定claude-code.path有一個(gè)通用排查思路先把所有第三方代理環(huán)境變量臨時(shí)清空回歸最干凈的網(wǎng)絡(luò)環(huán)境看問題是否消失。大部分登錄相關(guān)的詭異問題都是這一類原因引起的。7.2 會話中卡住或輸出中斷Claude Code 在處理特別長的上下文或者大規(guī)模重構(gòu)任務(wù)時(shí)偶爾會出現(xiàn)響應(yīng)中斷。我的經(jīng)驗(yàn)是把大任務(wù)拆成小任務(wù)來問每次只讓它處理一個(gè)模塊或一個(gè)功能成功率會高很多。另外重要操作前先存?zhèn)€檔claude --resume # 或手動保存會話用 --continue 恢復(fù)--resume可以恢復(fù)最近的會話不怕中斷丟上下文。我還會在長任務(wù)里定期把中間成果 commit 到 git 分支這樣即使 AI 跑偏了也能輕松回退到正常狀態(tài)。7.3 MCP 讀不到數(shù)據(jù)庫或數(shù)據(jù)不一致MCP 連接數(shù)據(jù)庫后最常見的問題是連不上或查出來的數(shù)據(jù)不是最新的。排查步驟我一般按這個(gè)順序確認(rèn) MCP Server 使用的數(shù)據(jù)庫賬號有遠(yuǎn)程訪問權(quán)限如果走 SSH 隧道確認(rèn)隧道端口映射正確檢查 MCP 配置里是否指定了正確的 database 名稱確認(rèn)讀取走的是主庫還是從庫延遲是否影響判斷這里我特別提醒一點(diǎn)MCP 里讀到的數(shù)據(jù)只能用于理解業(yè)務(wù)不要讓它影響你的架構(gòu)決策。生產(chǎn)系統(tǒng)的判斷還是要以監(jiān)控大盤、鏈路追蹤和真實(shí)壓測數(shù)據(jù)為準(zhǔn)。7.4 配額和限額問題持續(xù)高強(qiáng)度使用 Claude Code尤其是團(tuán)隊(duì)多人共享賬號時(shí)很容易遇到請求頻率限制或者周配額耗盡的提示。這類問題沒有太多取巧空間我這邊是這么處理的日常小任務(wù)補(bǔ)注釋、格式化、寫測試樁代碼使用輕量模型不占用頂級模型配額重要架構(gòu)設(shè)計(jì)任務(wù)集中在一個(gè)會話里完成避免反復(fù)開啟新會話重復(fù)消耗團(tuán)隊(duì)按服務(wù)模塊分配使用責(zé)任避免多人同時(shí)跑重型任務(wù)高峰期錯(cuò)峰使用把大規(guī)模重構(gòu)任務(wù)安排到非高峰時(shí)段執(zhí)行說到底配額管理也是治理的一部分。把它納入團(tuán)隊(duì)資源規(guī)劃里比臨時(shí)抱佛腳到處找解決辦法要靠譜得多。7.5 對話歷史保存與團(tuán)隊(duì)共享有些同事會問“Claude Code 怎么保存對話歷史”其實(shí) CLI 模式下每次會話都有日志記錄關(guān)鍵是找到并善用這些日志。我之前已經(jīng)在治理章節(jié)提過設(shè)置統(tǒng)一日志路徑的方法這里再說一個(gè)團(tuán)隊(duì)場景下的實(shí)用技巧把重要的 AI 會話輸出以 Markdown 形式導(dǎo)出到一個(gè)共享倉庫。具體的做法是在會話結(jié)束時(shí)讓 Claude Code 自己把討論內(nèi)容和結(jié)論整理成文檔請將本次會話的關(guān)鍵決策、生成的文件列表、遺留問題整理為一份 Markdown 文檔保存到 docs/ai-sessions/2025-xx-xx-points-service-review.md這樣每次重要改動都有據(jù)可查團(tuán)隊(duì)其他人也能通過這些文檔了解 AI 參與開發(fā)的完整脈絡(luò)避免“在 AI 會話里發(fā)生過什么”成為黑箱。寫在最后我的一些真實(shí)體會折騰了大半年 Claude Code我自己最深的體會是AI 不是用來替代工程師思考的而是用來放大工程師的思考效率的。你越清楚自己要什么、越懂得設(shè)定邊界它給你的幫助就越大。反之如果你自己都不知道系統(tǒng)該怎么設(shè)計(jì)就把問題拋給它它只會用漂亮的代碼包裝你的混亂最后把麻煩留到生產(chǎn)環(huán)境。我現(xiàn)在每天的工作流里Claude Code 仍然像一名實(shí)習(xí)生我會給它清晰的任務(wù)說明、約束條件和驗(yàn)收標(biāo)準(zhǔn)它負(fù)責(zé)快速出活我負(fù)責(zé)把關(guān)方向和質(zhì)量。它寫出來的東西我會看它給的建議我會復(fù)核它跑出來的測試我會再跑一遍確認(rèn)。這個(gè)過程聽起來比“全自動寫代碼”慢但真正長期跑下來系統(tǒng)的穩(wěn)定性、團(tuán)隊(duì)的可維護(hù)性都遠(yuǎn)遠(yuǎn)好于讓 AI 自由發(fā)揮的方案。開源生態(tài)里關(guān)于 Claude Code 的玩法一直在進(jìn)化MCP 協(xié)議也催生了不少新的集成方式。我的建議是保持關(guān)注但不要盲目追求花哨的用法。對生產(chǎn)級分布式系統(tǒng)來說能穩(wěn)定復(fù)現(xiàn)、能解釋清楚、能快速回滾永遠(yuǎn)比“看起來很酷”重要得多。先把這套“可驗(yàn)證、可治理、可擴(kuò)展”的原則落地再慢慢玩出屬于自己的最佳實(shí)踐這條路我試過走得通。