本文對象為多節點/並聯 Mac 上的 monorepo 建置團隊:用一張 watchman 與 git 輪詢對照表選監聽策略,用 sysctl/程序上限與節流閾值壓住 FSEvents 爆量,再把 建置鎖與磁碟驗收寫進同一本 runbook。延伸閱讀:《Nomad 親和、建置鎖與 1TB/2TB 水位》、《並聯叢集 rsync 決策矩陣》;互動連線品質可對齊《Mosh 與 SSH、flock 驗收》。
watchman 與 git 輪詢對照
原生路徑盡量讓 watchman 持有「單一真相」:它把目錄變更合併後再餵給 Metro、Vite、Jest 等工具,能把單次大規模 checkout 造成的事件尖峰折成可消化的批次。相對地,強制 CHOKIDAR_USEPOLLING=1 或純 git/輪詢後備路徑,CPU 開銷較可預期,但在十萬級小檔與高頻暫存檔場景容易落後或漏觸發,反而誘發「手動清快取—全量重建」的二級風暴。
| 策略 | 延遲與精準度 | 事件風暴風險 | 建議閾值/註記 |
|---|---|---|---|
| watchman + 嚴格 ignore | 低延遲;適合大樹增量。 | 可透過 settle 與忽略清單壓峰。 | 單 repo 活躍監聽根 ≤ 1–2 個;settle 建議 20–100 ms 級試跑後固化。 |
| 輪詢 fallback | 秒級起跳;易錯過極短暫檔案。 | 目錄巨大時變成掃描風暴。 | 僅在無守護行程或網路卷不支援 FSEvents 時啟用;輪詢間隔 ≥ 1 s 並縮小監聽根。 |
| 多工具各開一套 watcher | 看似解耦。 | 同一樹多路徑訂閱,峰值相乘。 | 並聯節點上預設不允許;改由單一 watchman 出口或多路併入同一設定。 |
sysctl/fs 限制與節流參數
風暴前半段常是「開檔描述子/ vnode 壓力」而不是編譯本身:請在每台 遠端 Mac 的驗收腳本裡記錄 sysctl kern.maxfiles kern.maxfilesperproc 與 CI 使用者下的 ulimit -n,並與實際峰值對帳。macOS 部分核心欄位隨版本與 SIP 政策而異,實務上以「登入層 launchctl limit maxfiles + shell ulimit」可重現的組合為準,把數字寫進鏡像/Ansible。
編譯節流閾值(建議起點,按 repo 實測調整):單機同時活躍 dev bundle ≤ 2;Metro/Webpack 類 worker 總量 ≤ CPU 實體核心數;單一 pipeline 在「大扇入 rsync 或 git clean 後」強制插入 watchman watch-del-all 冷卻步驟,避免舊訂閱與新路徑重疊。
可貼倉庫根目錄 .watchmanconfig(欄位以你團隊使用的 watchman 版本文件為準):
{
"settle": 50,
"ignore_dirs": [
"node_modules",
".git",
"dist",
"build",
"DerivedData",
".turbo"
]
}
驗收 shell 片段(併入節點開通或 CI pre-hook):
# 觀測:檔案上限與目前軟限制 sysctl kern.maxfiles kern.maxfilesperproc 2>/dev/null || true ulimit -n # 常見可調整層(實際語法依 macOS 版本與登入層而定,請先於 staging 驗證) ulimit -n 65536 # launchctl limit maxfiles <soft> <hard> # 由平台團隊寫入 plist/MDM
與大倉建置鎖協同
大倉並聯時,「誰能改依賴樹/誰能寫正式產物目錄」必須與檔案監聽生命週期同一個敘事:在 promote、子模組切換或全域 pnpm store 遷移前後,應先取得 建置鎖,再重啟或刷新 watchman,否則會出現半套 node_modules 上的海量 unlink 事件。排程器若採 Nomad/自研佇列,請避免「佇列層 max_parallel」與「腳本層 flock」各說各話;擇一為權威串列機制,另一僅作短逾時保險,細節可與Nomad × 建置鎖一文對表。
LOCK=/var/tmp/monorepo-mutation.lock
flock -n "$LOCK" bash -c '
git fetch --depth=1 origin "$SHA" && git checkout -f "$SHA"
watchman watch-del-all || true
watchman shutdown-server || true
CI_THROTTLE_BUNDLES=2 ./scripts/ci-build.sh
' || { echo "mutation or throttle busy"; exit 17; }
磁碟水位告警值建議與驗收清單
事件風暴與全量編譯最吃 磁碟水位:APFS 上除使用率外,還要檢時間機快照與「隱形」預留;並聯節點建議把告警接到同一套儀表板,與佇列深度聯動。
| 卷宗使用率 | 1TB 工作節點 | 2TB 工作節點 | 與監聽/建置協同 |
|---|---|---|---|
| < 70% | 維持既有並行;例行輪替 DerivedData。 | 可保留多分支快取;仍記錄趨勢。 | 允許完整 watchman 樹;維持節流參數不變。 |
| 70%–80% | 黃燈:收斂非關鍵扇出、評估升 2TB。 | 黃燈:清暫存與舊製品;預排停機整理。 | 暫停新增第二套 dev watcher;編譯 worker 降一檔。 |
| > 90% | 紅燈:硬停大型 rsync/git 大操作;先釋放快照與快取。 | 強制 watch-del-all 後只允許單一路徑增量直至回綠。 |
|
驗收勾選:① 每台節點 watchman version 與 watchman watch-list 根數符合策略;② 模擬一次大分支切換,p99 事件合併延遲與 CPU 尖峰在閾值內;③ 磁碟演練從 78% 拉回 60% 的全自動腳本可重跑。大型扇出參數請仍與《並聯叢集 rsync 決策矩陣》對齊。
FAQ
watchman 已裝仍爆量? 先查是否多工具重複訂閱同一樹,以及 ignore 是否漏掉大型暫存目錄;再以官方診斷指令確認合併視窗是否過短。
為何要在鎖內關 watchman? 大倉目錄整批替換時,舊訂閱會與新路徑交錯產生雜訊事件;關閉後由單一入口重建 watch,比調高全系統 ulimit 便宜。
1TB 是否不適合並聯 monorepo? 可用,但要把快取與製品分卷並嚴守 80% 黃線;否則 磁碟水位與重試風暴會讓 M4 空轉在 IO 等待上。
下一步:到 方案與價格 比對 1TB/2TB,再在 購買頁 依區位加機,讓 遠端 Mac 叢集承載本文閾值表。