預約視窗 · 鎖 TTL · 佇列優先順序 · 衝突可觀測
當 SSH、簽名與依賴快取都已就位,團隊仍會看到「同一臺機器上兩個 Job 爭用工作目錄」「美東產物覆蓋新加坡半成品」「鎖檔案懸掛導致佇列假死」。根因是席位與互斥沒有在架構評審裡與 Runner 拓撲同級對待;它們與任務鏈冪等鍵和staged publish強相關,缺欄位時排障只能依賴個人記憶。
同機雙寫稅:兩個任務共用同一檢出目錄或同一 DerivedData 根,表現為偶發連結錯誤與簽名不一致;標籤正確也無法拯救目錄級競態。
跨節點重複產物稅:同一構建號在兩地同時推進,指標切換前讀者看到撕裂集;沒有租約與版本指標時回滾只能猜時間點。
鎖懸掛稅:程序崩潰未釋放租約,後續任務永久等待;缺少 TTL、續租失敗告警與人工清理門檻會把平均恢復時間拉到小時級。
優先順序反轉稅:低優先順序長任務佔滿席位,高優先順序熱修被餓死;沒有二級佇列與搶佔策略時只能半夜手工 kill。
觀測盲區稅:只記錄構建時長卻不記錄 queue_wait_ms 與 lock_contention_count,評審會只能用「感覺慢」替代資料。
把以上五條寫成可勾選清單,再進入下一節選型互斥模型,才能從「能跑」升級到「可驗收的共享池」。與SSH 與 VNC 接力對照閱讀時,請區分互動會話與無人值守作業對鎖語義的不同假設。
三條路徑沒有絕對優劣,只有與團隊規模、跨區延遲預算與合規審計是否匹配。本地檔案鎖實現快但可觀測性弱;遠端協調服務(例如基於物件儲存或輕量協調器的租約表)增加依賴但能把衝突率變成指標;排程器內建佇列最省心卻要接受平臺語義。多地區 Mac 場景下還要把區域親和與失敗域寫進契約,否則鎖在 A 區、跑在 B 區會把 RTT 放大成排隊時間。
| 維度 | 本地檔案鎖 | 遠端協調租約 | 排程器佇列 |
|---|---|---|---|
| 一致性語義 | 依賴本地 FS 與單掛載點;跨掛載即失效 | 顯式租約 ID、TTL、續租與 fencing token | 平臺保證序列與重試;需核對標籤與併發上限 |
| 跨區適用性 | 弱;只適合單機池內互斥 | 強;可把租約表放在低延遲區並複製只讀副本 | 中;取決於 Runner 排程是否跨區透明 |
| 可觀測性 | 需自行埋點;常見只有 mtime | 租約表天然可匯出指標與審計欄位 | 平臺佇列深度與等待時間通常開箱 |
| 運維成本 | 低起步;後期排障貴 | 中;要處理時鐘漂移與腦裂預案 | 低;但複雜拓撲可能被平臺能力限制 |
| 典型踩坑 | NFS 鎖語義與本地鎖混用 | 續租失敗靜默、清理任務無租約 | 標籤風暴與隱式共享工作區 |
共享池是否可靠,取決於「衝突能否被度量」而不是「成功時能否偶爾跑完」。
若你已在實踐共享構建池 Runner 編排,把本節選型結論貼進架構說明,可避免「池子有了,但互斥仍靠口頭約定」的半截工程化。
下面六步刻意保持廠商無關:無論你用 Jenkins、GitHub Actions 還是自研排程,只要交付物一致,新同事可以在半天內驗證鏈路。每一步都應對應一條可檢查的變更描述;與任務鏈 handoff組合時,請把租約 ID 寫回信封。
定義席位上限:按 CPU、磁碟 IO 與互動會話需求給每臺 Mac 設定 max_concurrent_jobs,並在 Dashboard 公示。
凍結工作區字首:每任務獨立檢出目錄與 DerivedData 根,禁止多工共用可變字首;與快取鍵策略對齊。
選擇互斥層:單機池優先檔案鎖加本地哨兵;跨區池優先遠端租約;需要搶佔與多級佇列時回到排程器能力評估。
設定鎖 TTL 與續租:TTL 取構建 P95 的 2–3 倍並設硬上限;續租失敗必須告警,不得靜默失效。
定義佇列優先順序:熱修與主幹門禁高於長週期歸檔;同級內 FIFO 或公平輪轉寫清,避免「口頭插隊」。
演練腦裂與清理:隨機 kill 持有租約的程序,驗證清理任務只在租約過期後觸發且帶審計日誌。
LEASE_ID="${CI_PIPELINE_ID}-${CI_JOB_ID}"
LEASE_TTL_SEC=$(( BUILD_P95_SEC * 3 ))
curl -sf -X PUT "${COORD_URL}/leases/${LEASE_ID}" \
-H "Content-Type: application/json" \
-d "{\"ttl_sec\":${LEASE_TTL_SEC},\"owner\":\"${GITLAB_USER_LOGIN}\",\"region\":\"${RUNNER_REGION}\"}"
提示:示例中的協調端點可用物件儲存條件寫入、輕量 KV 或自建微服務實現;關鍵是 TTL、續租與 fencing 三角缺一不可。
沒有度量就沒有 SLO。建議至少採集 佇列等待分位、鎖衝突次數、續租失敗率 與 因互斥導致的構建取消率,並與構建時長並列展示;否則最佳化會誤判為「編譯慢」而反覆加核。排障順序建議先確認租約與佇列深度,再檢查產物指標與快取鍵,最後才懷疑工具鏈。
佇列先看:queue_wait_p95 大於單次構建入口時間 10% 時優先擴容席位或調整優先順序,而不是盲目最佳化編譯引數。
鎖再看:lock_contention_per_hour 連續升高時檢查是否有共享字首或未釋放租約。
產物最後:當 staged publish 與指標切換指標異常時,再回到位元組路徑與校驗欄位。
注意:清理懸掛鎖前必須確認沒有讀者仍持有舊指標;暴力刪除往往換來更長的 mystery outage。
下列三條來自大量跨區 iOS 與 macOS 流水線的經驗區間,用於立項前核對而非效能保證;你應用真實直方圖替換它們,並在評審附件保留原始分佈。
queue_wait_p95 大於端到端時長 15%,優先調整席位與優先順序,再考慮橫向加機器。| 團隊規模 | 釋出節奏 | 更穩的第一選擇 |
|---|---|---|
| ≤ 8 人 | 日更主幹 | 排程器佇列 + 每任務獨立工作區;單機檔案鎖加哨兵 |
| 9–30 人 | 多分支並行 | 遠端租約表 + 明確優先順序;區域親和讀 |
| 30 人以上 | 多租戶合規 | 強制租約審計 + 不可變構建號;獨立名稱空間 |
| 強合規 | 跨區域受限 | 分割槽協調服務 + 禁止公共讀桶;日誌留存與責任人欄位 |
個人筆記本、臨時借用機器與「誰有空誰 ssh」在審計隔離與併發一致性上會持續欠賬;即便鎖設計正確,底層節點休眠與更新視窗也會讓指標失真。相較之下,可合同化的雲端 Mac 節點才能把席位、租約與 SLA 落在可驗收條款上。
常見誤區:把「遠端桌面流暢」當成「無人值守作業健康」;互動會話與自動化作業對鎖與休眠的要求相反,混用會拖垮整條鏈。
若團隊既要 iOS 與 macOS 持續交付,又要給夜間迴歸與自動化留出確定性席位,自建固定資產往往卡在採購週期與多地佈線;借用個人裝置則難以滿足金鑰輪換與併發隔離。對需要生產級共享池與可觀測互斥 的場景,VpsMesh 的 Mac Mini 雲端租賃通常是更優解:按週期彈性計費、區域可選、節點專用可審計,讓佇列指標與池容量討論建立在真實可用性之上,而不是口頭承諾。