dsh-dual-proxy:DSH 下的 Agent 網關管理與在線 failover

前言

在 DSH 或同類 Agent 宿主裏跑模型請求,往往還要經過本機代理或上游網關。常見問題是:同一條代理對某個 API 通、對另一個不通,或者整段窗口裏某條路全掛;客戶端只配一個 HTTP_PROXY 時,失敗只能反覆在同一條死路上重試,既拖慢響應,也不利於排查。

DeepSeek Harness(DSH)社區把能力拆成插件維護。dsh-dual-proxy(維護者 gambn,分類:聯網工具)把「Agent 到模型端點的網絡路徑」當成可管理資源:在多個候選網關、環境變量裏的代理與直連之間自動選路,運行中用真實請求做通道驗證,失敗立刻切到下一條,無需重啓宿主、也無需改客戶端裏的固定代理地址。

下面介紹它的定位、行爲要點,以及作爲 DSH 插件時的安裝與配置。

這是什麼

dsh-dual-proxy 的英文簡介是:Agent gateway manager for DSH — online multi-gateway failover and channel health checks。同一套核心提供兩種形態:

  • DSH 插件(推薦):隨 DSH 啓停,在「設置 → 插件」裏改配置,可通過 routeHostFetch 把宿主進程內的 fetch 引到本代理;
  • 獨立進程:全局安裝 CLI,或掛 systemd 用戶服務,非 DSH 的 Agent 與腳本也能用。

npm 包版本爲 0.7.1,許可證 MIT。倉庫:https://github.com/gambn/dsh-dual-proxy;社區目錄頁:https://www.skillhub.cn/plugins/gambn/dsh-dual-proxy(獨立站點,與 DeepSeek / 幻方無官方從屬關係)。

核心功能

候選路與選路順序

客戶端連到本地監聽(默認 127.0.0.1:7898),由插件在候選之間切換。候選包括:upstreamHost:upstreamPort(或 upstreamUrl)、配置裏的 gateways、啓動環境中的 HTTP(S)_PROXY / ALL_PROXY(去重並排除自身監聽端口),最後補 直連。示意如下:

客戶端 → 127.0.0.1:7898
           ├── 網關 A(TLS 探測通過)→ 上游代理
           ├── 網關 B(TLS 探測通過)→ 上游代理
           └── 都探測失敗 → 直連

健康檢查與失敗處理

  • 按 healthIntervalMs 對 healthUrl 發 GET,響應碼 <500 視爲通道可用(401/403 也算端點活着);通過者設爲全局首選,全部失敗則清首選、下次請求重新掃描;healthIntervalMs 設爲 0 可關閉後臺驗證。
  • 每 host 偏好緩存(默認 TTL 60 秒,最多 1000 條 LRU):命中可跳過探測,失敗即切換。
  • 失敗網關默認冷卻 30 秒,期間排到隊尾;任一路剛失敗會觸發一次健康檢查(1 秒內防抖),不必等下一個週期。

HTTPS CONNECT 與普通 HTTP

  • CONNECT(443):對候選先做 TLS 握手探測,通過的纔開隧道;隧道建立後只轉發字節,隧道內失敗無法換路。
  • 普通 HTTP:請求體先緩衝(上限 8 MB),按順序換路重放;建連用 attemptTimeoutMs,等響應頭用 responseTimeoutMs。

重放與安全相關默認

自 0.6.0 起,POST / PATCH 在連接建立後失敗默認不再自動換路重放,返回 502;需要舊行爲可打開 retryNonIdempotentAfterSend。可選 retryNonIdempotentWithIdempotencyKey:僅當請求帶非空 Idempotency-Key / X-Idempotency-Key 時,允許發送後重放非冪等請求。

上游代理 URL 可帶 user:pass,連接時發送 Proxy-Authorization: Basic;0.7.0 僅支持 http:// 上游代理,upstreamUrl 傳 https:// 會報錯。日誌只寫主機、網關與原因,不記錄請求內容。

接入 DSH 宿主

打開 routeHostFetch 後,進程內所有 fetch(不限於模型調用)會先到本代理再選路;pnpm、git 等子進程不繼承,仍走啓動環境代理。插件禁用或卸載時會還原原來的 undici dispatcher。

安裝與啓用

運行要求 Node.js ≥ 22.19.0(undici 8);插件形態還需要 dsh ≥ 0.1.7。

先做插件安裝:

dsh plugin --profile web add dsh-dual-proxy

也可僅安裝獨立 CLI:

npm install -g dsh-dual-proxy

安裝後確認 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 含 dsh-dual-proxy(包內 cordis.patch.yml 會參與組合),再重啓 dsh web。若曾跑過獨立進程或 systemd 用戶服務,先釋放默認端口 7898:

systemctl --user disable --now dsh-dual-proxy 2>/dev/null

插件以當前 DSH 進程權限運行;安裝前建議自行查看倉庫源碼與 MIT 許可證。

典型配置(DSH 插件)

啓用後在「設置 → 插件」中可改下列字段(節選,默認值以 README 爲準):

字段 默認 說明
listenHost 127.0.0.1 監聽地址
listenPort 7898 監聽端口
upstreamHost / upstreamPort 127.0.0.1 / 7897 第一個候選網關
upstreamUrl 空 非空時覆蓋 host/port,可含認證
gateways 空 額外候選,host:port 逗號分隔
routeHostFetch false bundle patch 裏默認可能爲打開
healthUrl https://api.deepseek.com 通道驗證;空則關閉後臺驗證
healthIntervalMs 60000 健康檢查間隔;0 關閉
fastFailTimeoutMs 2000 緩存/首選路徑的建連超時
cooldownMs 30000 失敗網關冷卻
attemptTimeoutMs 5000 每次嘗試/探測超時
responseTimeoutMs 60000 普通 HTTP 等響應頭上限
verifyTls true 443 是否 TLS 探測

獨立進程與 Claude Code 啓動器

不掛 DSH 時,可直接跑 CLI,例如:

node bin/dsh-dual-proxy.js --listen-port 7898 --upstream-port 7897 \
  --gateway 127.0.0.1:12334 --health-url https://api.deepseek.com

Claude Code 爲原生二進制,不能像 DSH 那樣改進程內 fetch;可用包內 claude-dual-proxy 在啓動器裏起代理,再給子進程設 HTTP_PROXY / HTTPS_PROXY:

claude-dual-proxy --listen-port 7896 --gateway 127.0.0.1:12334 -- --resume

systemd 用戶服務模板在倉庫 contrib/。

適用場景與注意

適合:本機有多條代理或網關、模型/API 請求需要在線 failover 與通道探測的 DSH web 配置;或非 DSH 腳本希望統一走一個本地入口選路。

邊界(README 已說明):只處理 HTTP/1.1 的 CONNECT 與普通 HTTP;不做透明代理、不接管 UDP;不校驗證書、不做鑑權;默認只綁回環,把 listenHost 改成非迴環會在啓動時告警。全部候選失敗返回 502。

結尾

dsh-dual-proxy 把多網關、環境代理與直連握在同一本地入口,用健康檢查與失敗切換減少「單點代理拖死整批請求」的情況,並可選把 DSH 宿主內的 fetch 接入選路邏輯。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜