遠端 Mac上跑 dotnet restoremsbuild -t:restore 時,跨境瓶頸多半落在NuGet.Config 來源鏈全域套件夾競爭鎖定還原RestoreLockedMode/CPM packages.lock.json)。本文提供決策矩陣、鏡像鏈範例、MaxHttpRequestsPerSource 與落地步驟。請先看首頁技術部落格;延伸Gradle/Maven 快取矩陣拉取穩定性 FAQCI 預拉與版本一致

場景痛點與可執行決策矩陣

誰該讀:Apple Silicon 遠端機、macOS runner 或共享 Mac 上建置 .NET 的團隊。痛點:(1)機器與儲存庫 Config 疊加仍直連 api.nuget.org;(2)缺 packageSourceMapping 誤走公共鏡像;(3)共用 globalPackagesFolder 鎖競爭;(4)CI/本機 SDK 不一 lock 解讀漂移。

場景packageSources 鏈策略MaxHttpRequestsPerSourceglobalPackagesFolder/NUGET_PACKAGESRestoreLockedMode/CPM
跨境弱網+鏡像區域鏡像優先,nuget.org fallback;加 packageSourceMapping816;共享機從低掛卷如 /usr/local/ci/nuget-pkg;可每 job 子目錄CI true;CPM 提交 packages.lock.json
高審計內網僅內部 feed;禁預設彙總48唯讀種子+週期預同步必鎖定;PR 檢 lock
開發機與 CI 分檔1632家目錄預設本地可關;合併前對齊 CI

一句話:先畫清來源順序與映射,再固定全域夾鎖定還原;要穩定出站可租用貼區域的遠端 Mac作還原節點。

MSBuild/CLI 參數與 NuGet.Config 鍵對照

參數或設定鍵典型寫法用途摘要
RestoreLockedModedotnet restore -p:RestoreLockedMode=true強制與 packages.lock.json 一致,禁止靜默升版
RestorePackagesWithLockFileDirectory.Build.props.csproj啟用 lock 產生/消費流程
MaxHttpRequestsPerSource<config>add key="..." value="12" />限制單一來源並發 HTTP,避免打爆鏡像
globalPackagesFolderNuGet.Config 或環境變數 NUGET_PACKAGES統一全域快取根;CI 與互動使用者宜分離
中央套件管理(CPM)Directory.Packages.props+專案 packages.lock.json版本集中;與 RestoreLockedMode 併用可鎖 CI

NuGet.Config 鏡像鏈範例(含 clear)

下列骨架示範「先清空再上鏈」,避免繼承到使用者目錄裡過期的 packageSources;請將 URL 換成貴司核准端點,並補上 packageSourceCredentials(若需要)。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="globalPackagesFolder" value="/usr/local/ci/nuget-pkg" />
    <add key="maxHttpRequestsPerSource" value="12" />
  </config>
  <packageSources>
    <clear />
    <add key="corp" value="https://artifacts.corp.example.com/nuget/v3/index.json" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

建議加 packageSourceMapping,公開/內部套件分流,避免誤打 nuget.org

落地步驟(≥5)

1

盤點 feed:列出所有 packageSources 與憑證需求,在遠端 Mac 上用 dotnet nuget list source 與實際還原日誌交叉驗證。

2

提交儲存庫級 NuGet.Config:clear、鏡像鏈、maxHttpRequestsPerSource;必要時以 NUGET_PACKAGES 覆寫全域夾而非依賴預設家目錄。

3

啟用 lock:傳統專案開 RestorePackagesWithLockFile;CPM 專案維護 Directory.Packages.props 與各專案 packages.lock.json,CI 一律 -p:RestoreLockedMode=true

4

限制 runner 併發:共享 Mac 上將還原/建置 job 的平行數壓到與頻寬匹配(常與 Gradle/npm 步驟共用節點,見站內快取矩陣文)。

5

包一層重試:對暫態 5xx/逾時以 2/4/8 秒退避重跑 dotnet restore,並上傳 --verbosity detailed 片段。

可引用閾值(Runbook)

  1. HTTP 併發:鏡像 429/重設時,將 maxHttpRequestsPerSource16 降至 8;多 job 先限同機還原數。
  2. 全域夾:CI 掛卷(如 /usr/local/ci/nuget-pkg)與互動使用者分離;可用 NUGET_PACKAGES,結尾列印 dotnet nuget locals all --list
  3. 鎖定:CI 固定 -p:RestoreLockedMode=true;更新 lock 僅經 PR,並在與正式 CI 相同 SDK 的遠端 Mac 映像產生 diff。

NuGet 還原 FAQ

RestoreLockedMode 開著卻一直報 lock 不符怎麼辦?

先對齊 dotnet --version 與目標框架;再在與 CI 相同的遠端映像上執行 dotnet restore --force-evaluate 產生新 lock,將 diff 當作一般程式變更審核。並確認 NuGet.Config 鏡像與開發機一致,否則解析結果會系統性偏差。

已設定內網鏡像,為何日誌仍出現 nuget.org?

常見原因是 packageSourceMapping 未涵蓋該套件 ID,或上層 Config 仍注入預設來源。請以 dotnet restore --verbosity detailed 追蹤實際 URL,並檢查專案層與機器層 Config 合併順序。

多台 job 共用同一 globalPackagesFolder 會不會變慢?

會。NuGet 會對快取目錄加鎖,過高併發會讓還原排隊。共享遠端 Mac 應限制同機平行還原數,或為高衝突 pipeline 指定每 job 子資料夾後再週期合併快取。

總結:2026 年在遠端 Mac做 .NET 跨境還原,請用決策矩陣選定鏡像鏈、MaxHttpRequestsPerSourceglobalPackagesFolder鎖定還原組合,再以儲存庫級 NuGet.Config五步落地固定行為。若希望還原與建置穩定貼近目標區域、並把快取留在專用節點,可租用 MacPull 遠端 Mac承載 NuGet 全域夾與 CI。免登入導覽:首頁購買頁定價說明中心;更多文章見技術部落格

遠端 Mac × .NET NuGet CI

鎖鏡像、鎖 lockfile,跨境還原更可預期

首頁、定價、購買與說明中心皆可免登入瀏覽;部落格另有 JVM/npm 快取與拉取 FAQ 可對照。