← 返回開發日記

Mac M4 CI 什麼時候該拆機?同機部署到雙節點架構的決策模型與遷移步驟(2026)

OpenClaw · 2026.06.23 · 約 11 分鐘閱讀

Mac M4 CI 構建節點與 OpenClaw Gateway 雙節點架構示意

六月初我們把 Xcode CI 和 OpenClaw Gateway 塞進同一台加拿大 M4,靠 launchd Nice=-5 和限制並行編譯撐了兩週。第三週起,業務同事開始在 IM 裡抱怨「Gateway 又卡了」——建置日誌顯示一切正常,curl 健康檢查卻在尖峰時段從 50ms 漂到 400ms 以上。調了並行數、清了 DerivedData、甚至臨時升到 24GB 方案,問題只是從「每天兩次」變成「每天一次」。

這不是設定寫錯,而是同機資源模型到了天花板。連接埠不衝突(20300 vs 18789),CPU 核心數也夠,真正打架的是統一記憶體與 swap。本文接續 同機部署與 launchd 調校 之後的路徑:什麼時候必須拆成雙節點、拓撲怎麼畫、遷移怎麼切流而不炸 Channels。官方記憶體與行程行為可參考 Apple 的 Xcode 建置快取文件;Tailscale 組網見 Tailscale 安裝指南

結論先行:分水嶺在資源隔離,不在「再買一台機器」。

  • 四條硬信號,滿足任一即拆

    建置 ≥50 次/天、並行 ≥3 路、Gateway 面向終端使用者、或 swap 一週內 ≥3 次 Critical——繼續同機調 Nice 只是拖延。

    ≥50 次/天

  • 最小雙節點:建置機 + Gateway 專機

    建置節點保留 24GB+ 與大容量 SSD;Gateway 節點 16GB 足夠常駐 ~500MB。兩台 M4 經 Tailscale 內網互聯,公網只暴露必要入口。

    16GB Gateway 專機

  • 遷移核心:狀態與 DNS,不是重裝

    rsync 設定目錄、複用 token、Tailscale MagicDNS 切流;建置機不停機,Gateway 藍綠切換視窗控制在 15 分鐘內。

    藍綠 ≤15 min

1. 為什麼同機方案會「突然不夠用」

很多團隊的第一台雲端 Mac 同時承擔三件事:跑 xcodebuild、掛 OpenClaw Gateway 18789、偶爾 VNC 上去點鑰匙圈。初期負載低,16GB 看起來綽綽有餘。隨著分支增多、UI 測試並行、Channels 從內部試跑變成對外服務,記憶體曲線從「鋸齒」變成「平台」——建置結束後的 10 分鐘裡,compressed 頁面仍佔 8GB 以上,Gateway 的 heap 繼續被擠進 swap。

同機調校(降並行、提 Nice、清快取)解決的是尖峰重疊機率,不能消滅尖峰本身。當兩個高峰在時間軸上幾乎必然重疊——例如亞太白天建置、北美晚間 IM 尖峰——你就不是在最佳化參數,而是在賭排程器。Apple Silicon 的統一記憶體沒有獨立顯存緩衝,Xcode 與 Node.js Gateway 爭的是同一塊實體池;memory_pressure 進入 Warn 後,延遲抖動對使用者是可感知的,對 CI 則是偶發逾時與簽署步驟失敗。

拆機的本質不是「擴容神話」,而是把不可壓縮的尖峰拆開:讓建置尖峰只打在建置節點,讓 Gateway 常駐記憶體永遠不被 xcsbuildd 擠佔。這與 GitHub Actions 自建 macOS Runner 上雲端 Mac 裡「專用 Runner 不混桌面」是同一邏輯,只是這裡拆的是 Gateway 與 CI。

2. 三種拓撲分類:同機、雙節點、三節點

先歸類再選型,避免一上來就「加兩台」:

  • T0 同機共存:一台 M4 同時跑 Xcode Server / 自建 Runner + Gateway。適合日建置 <30 次、Gateway 僅內部、可接受偶發延遲。
  • T1 雙節點(本文主角):節點 A 專職 CI(24GB+、大 SSD);節點 B 專職 Gateway(16GB 即可)。Tailscale 或機房內網互通,Channels 與 Dashboard 指向 B,建置觸發走 A。
  • T2 三節點:在 T1 上再拆「簽署/上傳專機」或「並行測試專機」。當日建置 >150 次、或 TestFlight 上傳與編譯必須硬隔離時再考慮;否則 T1 足夠多數中小團隊。

非對稱結論再說一次:問題不在 M4 效能不夠,而在你把兩種 SLA 不同的服務綁在同一記憶體池裡。 Gateway 要 99.9% 平穩回應;CI 要吞吐。同機是在用一套 SLA 妥協兩個目標。

T1 雙節點:建置機 + Gateway 專機 節點 A · CI 建置機 M4 24GB+ · 1TB SSD xcodebuild / Runner DerivedData 本機 :20300 Xcode Server 節點 B · Gateway 專機 M4 16GB · 256GB OpenClaw Gateway Channels / Dashboard :18789 穩定低延遲 Tailscale <5ms 工程師 SSH / CI 觸發 → A;IM / 行動端 / Agent → B
雙節點最小模型:建置尖峰與 Gateway SLA 實體隔離

3. 同機 vs 雙節點 vs 升配:怎麼比

Mac M4 CI 擴容路徑對比(2026)
維度 繼續同機調校 Nice / 降並行 單機升 32GB 加記憶體不換拓撲 拆成雙節點 CI + Gateway 分機
解決根因緩解尖峰重疊抬高記憶體天花板隔離兩種 SLA
Gateway 延遲仍隨建置抖動改善但非消除建置期可保持 <100ms
月成本(粗算)最低中(升配差價)中(+16GB 小機)
維運複雜度中(多一台、Tailscale)
適合階段日建置 <30並行 2 路、內部 Gateway≥50 次/天或對外 Gateway
拆機觸發信號檢查表(滿足任一建議進入 T1)
信號 閾值 觀測方式 誤報排除
建置頻率≥50 次/天CI 日誌 / Runner 計數排除手動本機 Archive
並行路數≥3 路全量建置xcodebuild -jobs 與佇列深度輕量 lint 不算一路
Gateway 受眾終端使用者 / 7×24 Channels產品側 SLA 要求純內部 webhook 可暫緩
記憶體壓力一週內 ≥3 次 Criticalmemory_pressure 日誌一次性洩漏需先排查
磁碟爭用月產物 >50GB 且 I/O wait 高df -h + iostat先清 archive 再判斷
升配不能替代拆機
32GB 同機適合「並行 2 路 + Gateway 內部試跑」。若 Gateway 已對外,升記憶體只是把抖動從每天三次變成每天一次——使用者仍會覺得「又卡了」。

4. 場景怎麼選:決策矩陣

  • 兩人團隊、日建置 <20、Gateway 僅自用:留在 T0,做好 同機 launchd 調校 即可。
  • 亞太觸發建置、Gateway 服務 IM 使用者:直接 T1。Follow-the-sun 下尖峰幾乎必重疊,同機必輸。
  • 已有 GitHub Actions 雲端 Runner,Gateway 剛上線:Runner 在 A,Gateway 放 B;不要在 Runner 機上再掛 18789。
  • TestFlight 上傳與編譯搶磁碟:先 T1;仍不夠再 T2 加簽署/upload 專機,參考站內 TestFlight 專文,勿與本文混為一談。
  • 預算只夠一台機:優先保證 Gateway SLA,建置改夜間批次或降並行——這是妥協,不是長期架構。

5. 推薦組合(可疊加)

  1. 最小雙節點棧:Hashvps 加拿大 M4 24GB(A,CI)+ M4 16GB(B,Gateway)+ Tailscale tailnet + openclaw doctor 週檢。適合從 T0 升級的多數團隊。
  2. CI 混合棧:A 機自建 Runner 接 GitHub Actions;B 機 Gateway + Channels。編排層在 GitHub,執行面在 macOS,Gateway 不背建置尖峰。與 2027 macOS 建置市場變遷 裡的「環境主權」方向一致。
  3. 可觀測棧:在 B 機常駐 Gateway 延遲探針(curl 5s 間隔)+ A 機建置結束 hook 寫 memory_pressure 快照;兩週資料足以向管理層證明拆機 ROI。

6. 遷移前常見誤區

  • 先停機建置再遷 Gateway:建置停機成本高;應 Gateway 藍綠、建置不停。
  • 新機器重裝而不 rsync 狀態~/.openclaw、token、Channels 配對狀態遺失會導致全員重登。
  • 公網雙 IP 同時暴露 18789:切流期應用 Tailscale 或內網 DNS,避免兩個 Gateway 同時接 Channels。
  • 建置機刪 Gateway 目錄太早:回滾視窗內保留舊機 Gateway 行程,僅改 DNS 指向。
  • 忽視時鐘與憑證:兩台機 NTP 偏差 >30s 會導致 token 驗證偶發失敗;遷移日先 sudo sntp -sS time.apple.com

7. 落地步驟:7 步完成雙節點遷移

以下 Runbook 假設:原機 mac-ci-01 同機執行 CI+Gateway;新購 mac-gw-02(16GB)專跑 Gateway。Tailscale 已安裝(詳見 OpenClaw 日常維運 Runbook)。

第 1 步:基線快照(遷移日前一天)

在原機記錄 Gateway 延遲 P50/P95、建置次數、memory_pressure 分佈,作為拆機後對比。匯出 openclaw status 與 Channels 清單截圖。

bash — 基線:Gateway 延遲與記憶體壓力
# 延迟采样 60 次
for i in $(seq 1 60); do
  curl -o /dev/null -s -w "%{time_total}\n" http://127.0.0.1:18789/health
  sleep 5
done | sort -n | awk '{a[NR]=$1} END{print "p50="a[int(NR*0.5)],"p95="a[int(NR*0.95)]}'

memory_pressure
vm_stat | head -8

第 2 步:新機初始化與 Tailscale 入網

mac-gw-02 完成 macOS 更新、安裝 Homebrew、Node、Tailscale;確保與 mac-ci-01 互 ping <5ms。不要在新機跑任何 xcodebuild

第 3 步:rsync Gateway 狀態(維護視窗開始)

bash — 從原機同步 OpenClaw 設定到 Gateway 專機
# 在原机 mac-ci-01 执行;先停 Gateway 避免写入分裂
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist

rsync -avz --delete \
  ~/.openclaw/ \
  builder@mac-gw-02.tailnet-abc.ts.net:~/.openclaw/

# 同步 launchd plist
scp /Library/LaunchDaemons/com.openclaw.gateway.plist \
  builder@mac-gw-02.tailnet-abc.ts.net:/tmp/

第 4 步:新機啟動 Gateway 並本機驗收

bash — 在 mac-gw-02 載入服務與健康檢查
sudo cp /tmp/com.openclaw.gateway.plist /Library/LaunchDaemons/
sudo launchctl load /Library/LaunchDaemons/com.openclaw.gateway.plist

openclaw doctor
curl -s http://127.0.0.1:18789/health
sudo lsof -iTCP:18789 -sTCP:LISTEN

第 5 步:切流——Tailscale MagicDNS 或反向代理

將團隊使用的 Gateway 主機名(如 gateway.tailnet-abc.ts.net)解析到新機;行動端與 Channels 設定改指向新 MagicDNS 名稱。切流期間不要在原機重啟 Gateway。

第 6 步:建置機減負

確認 Channels 與 Dashboard 在新機正常後,在原機卸載 Gateway launchd,釋放記憶體給 CI。可將並行編譯任務數調回 5–6(24GB 機)。

bash — 原機建置機移除 Gateway,恢復 CI 並行
# mac-ci-01:确认已无流量打到 18789 后
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist
sudo mv /Library/LaunchDaemons/com.openclaw.gateway.plist \
        /Library/LaunchDaemons/com.openclaw.gateway.plist.bak

defaults write com.apple.dt.Xcode \
  IDEBuildOperationMaxNumberOfConcurrentCompileTasks 6

第 7 步:觀察 48 小時與回滾預案

保留原機 .openclaw 備份與 plist.bak 七天。若新機 Gateway P95 >200ms 或 Channels 掉線,將 DNS 指回原機並 launchctl load 舊 plist——全程無需動 CI 佇列。新閘道安裝細節可對照 OpenClaw 遠端 Mac 安裝部署

8. FAQ

Q1. 只有 16GB 一台機,能不能先拆「邏輯角色」而不買第二台?

不能代替實體拆機。 你可以用時段錯開(夜間建置、白天 Gateway),但 Follow-the-sun 或 7×24 Channels 下遲早再撞尖峰。邏輯拆分的唯一價值是驗證「遷走 Gateway 後延遲是否恢復」,用於向採購證明第二台的必要性。

Q2. 雙節點必須用 Tailscale 嗎?

不必須,但強烈推薦。 同一雲端廠商內網、WireGuard 自建、或 SSH 隧道均可;Tailscale 的優勢是 MagicDNS、ACL 與低維運。兩台 Hashvps 加拿大 M4 在同區域時,內網 RTT 通常 <2ms,足夠 Gateway 調 A 機上的建置 webhook。

Q3. 雙節點比單機 32GB 貴多少?

取決於方案,但常接近「24GB 建置機 + 16GB 小機」vs「單機 32GB」。 關鍵不在絕對差價,而在 Gateway SLA 是否可證明:對外服務團隊應用停機時間算帳,而非只看月租。

Q4. GitHub Actions 託管 Runner 還要自建 Mac 嗎?

看環境主權。 託管 macOS 按分鐘計費,適合波峰;自建雲端 Mac 適合固定日建置量 >50 且要控金鑰與 DerivedData。Gateway 仍建議獨立節點,與 Runner 託管與否無關。

Q5. 遷移失敗最快回滾怎麼做?

DNS 指回 + 原機 launchctl load。 不要在回滾日跑大規模建置;先驗證 Gateway health 與一條 Channel 訊息,再開放 CI。狀態目錄保留雙份直至新業務指標穩定。

9. 總結

Mac M4 CI 拆機不是失敗,而是同機調校成功後的自然下一階段:你已經證明業務需要同時跑建置與 Gateway,只是實體上不該再擠同一條記憶體。記住四條硬信號、用 T1 雙節點隔離 SLA、用 7 步 Runbook 做藍綠切換——分水嶺在資源隔離,不在機器數量。

若你正卡在「Gateway 又卡了但建置不能停」的窗口,優先加一台 16GB Gateway 專機,比繼續調 Nice 更接近根治。建置繼續跑在 24GB 雲端上,Agent 與使用者在另一台機器上獲得穩定 18789——這才是 2026 年小團隊能負擔的「準生產」拓撲。

雙節點拆機,從兩台雲端 Mac mini 開始

Xcode CI 與 OpenClaw Gateway 分機後,建置機需要 24GB 與大 SSD 扛 DerivedData,Gateway 機 16GB 即可 7×24 低延遲在線。Hashvps 加拿大 M4 裸金屬、獨享 IPv4、SSH/VNC 開箱即用,兩台機器同區域組網延遲低,適合作為 T1 雙節點的起步配置——比單機硬升 32GB 更能隔離 swap 抖動。

若你正在規劃從同機遷到雙節點, Hashvps 雲端 Mac mini M4 是性價比較高的第二台起點—— 立即了解方案 ,讓 Gateway 與 CI 各得其所。

Hashvps · Mac 雲服務

構建機與 Gateway,分機更穩

24GB CI 節點 + 16GB Gateway 專機,裸金屬 macOS、獨享 IP,Tailscale 內網即用。

前往首頁
限時優惠