Skip to Content
平台維運地端 Edge Workers

地端 Edge Workers

在地端 TeamSync 套件上,Edge Workers 是選用的附加元件。後端依 EDGE_WORKERS_PROVIDER 選擇 Edge Worker provider:cloudflare(預設,即執行於 Cloudflare Workers for Platforms 的 TeamSync 雲端)或 onprem(部門 Worker 跑在套件內自架的 workerd 上)。其他任何值都是設定錯誤(edge_workers_provider_invalid:EDGE_WORKERS_PROVIDER must be 'cloudflare' or 'onprem')。雲端 runtime 見架構;本頁描述後端 5.21.0 的地端 runtime,先寫給 Worker 作者與串接方,再寫給負責套件的維運人員。

保持不變的部分

  • Worker 專案、builder、成員 API、UI、生成的 OpenAPI 文件、存取模式、簽章通道與公開通道,以及 release generation 檢查,都與 TeamSync 雲端相同。
  • builder 產出的 bundle 逐位元組原樣執行。儲存 binding 同樣是 TEAMSYNC_DEPARTMENT_STORAGE → SQLite Durable Object class TeamSyncDepartmentStorage,資料存在 host 的本機磁碟。
  • 每個請求都由同一份 dispatcher 程式碼回答,因此斷言檢查、body 與 query 上限、錯誤信封({code, message, requestId},附 cache-control: no-store 與 x-teamsync-request-id)以及公開通道的 CORS header 都與雲端相同。
  • fetch() 是唯一的對外原語。Worker 程式碼無法使用原始 TCP connect():bundle 不能匯入 cloudflare:sockets(builder 以 source_import_forbidden 拒絕)。

附加元件的運作方式

docker-compose.edge-workers.yaml 為套件加上三個容器:

容器角色
edge-hostedge-hostd(PID 1),加上每個部門 Worker 一個釘選版本的 workerd 行程(各自使用獨立的使用者 id),以及一個為未知 Worker 回應的 fallback 行程。workerd 1.20260924.1、Node 24.21.0。
edge-gateway原版 nginx:1.28-alpine relay;進入 edge-host 的唯一途徑。後端經 http://edge-gateway:8080 呼叫它,用於簽章通道呼叫、部署與控制呼叫。
edge-artifacts專用的 S3 相容儲存,存放專案壓縮檔與 bundle(bucket edge-worker-artifacts);不對外公開任何連接埠。

edge-host 只連在內部的 edge_control 網路(預設子網路 172.31.253.0/29)與 edge_egress 網路上,從不連到套件網路:Worker 程式碼無法連到 MySQL、Redis、Qdrant、MinIO、edge-artifacts 或後端。地端沒有 dispatch namespace;outbox 資料列改帶部署範圍 onprem:<scope id>(見架構)。

公開 URL 與用戶端 IP

項目地端的值
公開 URL<EDGE_WORKERS_PUBLIC_BASE_URL>/public/<script>,即 https://<kit host>/edge/public/dw-<48 hex>;API 的公開 URL 路由回傳它。base 必須是 HTTPS 且路徑恰為 /edge,否則該路由回 503 Department Worker public URL is unavailable。套件的 HOST 不是 HTTPS 時,安裝程式會拒絕。
速率限制(套件 nginx,/edge/public/)每個用戶端位址每秒 50 個請求、突發 100;超出的請求得到 nginx 自己的純文字 429(不是 JSON 信封)。
請求 body套件 nginx 與 relay 接受最多 6 MiB;dispatcher 自己的 1 MiB 請求 body 上限照樣適用,與雲端相同。
代理逾時套件 nginx:連線 5 秒,送出/讀取 75 秒。relay:連線 5 秒,送出/讀取 70 秒。
用戶端 IP套件 nginx 看到的位址($remote_addr)。nginx 會覆寫 X-Real-IP、X-Forwarded-For、CF-Connecting-IP 與 True-Client-IP,用戶端自己送來的這些 header 會被丟棄,因此 IP 允許清單類的存取模式比對的就是這個位址。套件前方若有 NAT 或負載平衡器,所有呼叫者都會共用它的位址。
request.cf地端沒有地理位置或機器人偵測資料。

執行期限制

雲端的每次呼叫 CPU 上限在地端不適用;每次呼叫改用牆鐘時間預算,記憶體與儲存則以每個 Worker 行程為單位設上限。雲端的值見限制。

限制地端預設(環境變數、範圍)超過時
每次呼叫的牆鐘時間30 000 ms(EDGE_HOST_INVOCATION_TIMEOUT_MS,最大 300 000;無效值退回 30 000)429 worker_limit_exceeded Worker execution limit exceeded(與雲端 CPU 上限相同的信封)。
CPU 看門狗每 1 秒做一次健康探測,逾時 1 秒;連續 2 次失敗該 Worker 行程被終止並重新啟動。10 分鐘內 3 次 → 隔離 5 分鐘,每次加倍,最長 1 小時;隔離中的 Worker 回 503 worker_unavailable。新的啟用或 edge-hostctl clear-quarantine 會結束隔離。
JavaScript heap128 MiB(EDGE_HOST_WORKER_HEAP_MB,16–4096)行程致命錯誤:Worker 重新啟動;進行中的請求得到 502 worker_execution_failed(若回應 header 已送出則連線被中斷)。
常駐記憶體512 MiB(EDGE_HOST_WORKER_RSS_MB,32–65536),每 1 秒檢查行程被終止並重新啟動。
每個 Worker 的儲存2 GiB(EDGE_HOST_WORKER_STORAGE_GB;純數字代表 GiB,也可寫成 512MiB 這類大小),每 10 秒量測Worker 被停止(503 worker_unavailable),資料保留;部署以 edge_host_storage_exceeded 失敗,直到維運人員調高預算(edge-hostctl set-budget)。
資料檔案系統水位線可用空間維持在 max(10 %, 5 GiB) 以上(可用 EDGE_HOST_DISK_WATERMARK_BYTES 覆寫),每 1 秒檢查成長最快的 Worker 若自身成長占下降量至少一半,就被停止;否則 host 回報 edge_host_disk_low。以 edge-hostctl resume 恢復。
子請求500:簽章斷言的 limits.subrequests(後端 EDGE_WORKERS_LIMIT_SUBREQUESTS),公開通道則為 EDGE_WORKER_SUBREQUESTS。以每個 Worker 行程為單位共用:每個執行中的呼叫把自己的額度加進同一個池,沒有呼叫在執行時池子歸零。Worker 的 fetch() 拋出 Too many subrequests (TeamSync on-prem subrequest limit);handler 未攔截時,生成的 runtime 回 500 worker_execution_failed。
日誌每個 Worker 每秒 200 行、256 KiB(EDGE_HOST_LOG_LINES_PER_SECOND、EDGE_HOST_LOG_BYTES_PER_SECOND),突發 ×2超出的行被丟棄;每秒一行 worker_log_dropped 計數。
行程/開啟檔案每個 Worker 256 個(EDGE_HOST_WORKER_NPROC)/每個行程 4096 個(EDGE_HOST_WORKER_NOFILE)作業系統資源上限(RLIMIT_NPROC/RLIMIT_NOFILE)。
每台 host 的 Worker 數50(EDGE_HOST_MAX_WORKERS,由安裝程式依 --edge-workers-max 寫入)再多一個 Worker 的首次部署以 edge_host_capacity_exhausted 失敗。
Bundle 大小1 B 到 5 MiB部署以 edge_host_release_too_large 失敗。
相容日期不得晚於釘選 workerd 的日期:5.21.0 為 2026-09-24部署以 edge_host_compatibility_date_unsupported 失敗;格式錯誤的日期以 edge_host_compatibility_date_invalid 失敗。內附範本使用 2026-08-14。

簽章斷言中的 CPU 值(後端 EDGE_WORKERS_LIMIT_CPU_MS)在地端沒有作用:地端 entry 會忽略它。每次部署都會重新啟動 Durable Object:舊行程停止,新行程在同一份儲存上啟動,新舊版本不會同時執行。

對外連線

Worker 的 fetch() 可到達網際網路與客戶的區域網路,但排除以下固定拒絕清單:

拒絕的範圍原因
169.254.0.0/16、fe80::/10鏈路本地位址,包含雲端 metadata 位址
127.0.0.0/8、::1/128迴路位址
edge 控制子網路(預設 172.31.253.0/29)附加元件的內部控制網路

套件的服務因為 edge-host 不在它們的網路上而無法連到;套件自己的公開位址(它的 nginx)則和任何區域網路用戶端一樣可以連到。TLS 信任公用瀏覽器 CA,加上可選的站台 CA bundle /etc/edge-host/ca/extra-ca.pem(以 setup-edge-workers-onprem.sh --apply --extra-ca-certs <PEM> 安裝;bundle 必須含有 CA:TRUE 的簽發者)。主機名稱驗證維持開啟;自簽的 CA:FALSE 伺服器憑證會以 TLS peer's certificate is not trusted 失敗。

請求路由與錯誤

host 依斷言中的 script 名稱路由簽章通道呼叫,依路徑路由 /public/<script>/…。它自己的回應使用 dispatcher 的信封;在 /public/ 上附帶 dispatcher 的 CORS header。見錯誤。

情況狀態code/message
已退役、未知或從未啟用的 Worker(斷言驗證後由 fallback 行程回應)404worker_not_found/Worker not found
Worker 正在啟動、重新啟動或切換到新 release暫留後服務請求最多等待 EDGE_HOST_HOLD_MS(預設 30 秒,1000–120000 ms)。
暫留逾時,或暫留上限已滿(每個 Worker 256 個請求、每個請求 1 MiB body、每個 Worker 16 MiB body、總計 64 MiB)503worker_unavailable/Worker unavailable
Worker 被隔離或因儲存而停止503worker_unavailable/Worker unavailable
回應 header 送出前就連不到 Worker 行程502worker_execution_failed/Worker execution failed
超過牆鐘時間預算429worker_limit_exceeded/Worker execution limit exceeded
套件 nginx 的公開速率限制429nginx 的純文字回應

重新部署時,host 會暫留該 Worker 的請求,而不是讓新舊版本並行。把 503 worker_unavailable 當成「稍後重試」。

部署結果

部署使用與雲端相同的 API 與狀態(錯誤)。地端 provider 會在修訂版與部署票證上記錄以下 error_code:

error_code類別原因
edge_host_release_put_failed可重試上傳到 host 時傳輸失敗,或得到不確定的回覆。
edge_host_host_busy、edge_host_host_maintenance可重試host 回 503 host_busy/host_maintenance(重複的 host 為原文)。
edge_host_fenced延後備份圍欄 開啟中:部署回到 pending,error_message 為 activation deferred by backup fence,不延遲,且不計入嘗試次數。
edge_host_config_invalid終止host 拒絕後端的憑證(401/403)。
edge_host_release_digest_mismatch、edge_host_compatibility_date_invalid、edge_host_compatibility_date_unsupported、edge_host_release_too_large終止host 拒絕上傳(422)。
edge_host_release_invalid終止新 release 的 canary 或啟動失敗;前一個 release 繼續服務。
edge_host_release_missing終止啟用時 host 上已沒有該 release。
edge_host_script_retired終止Worker 已退役(部門刪除時仍在佇列中的部署也是)。
edge_host_storage_exceeded終止Worker 超過儲存預算。
edge_host_capacity_exhausted終止已設定的 Worker 數已達 EDGE_HOST_MAX_WORKERS。只有這個終止代碼會同時公開 error_message:The host's Worker capacity is reached; re-run setup with a larger --edge-workers-max。既有 Worker 的重新部署不計入。
edge_host_activate_uncertain、edge_host_fence_diverged不確定啟用回覆遺失,且 90 秒的 host 回讀無法證明結果。公司管理者可以修復該票證。

啟用回覆遺失時,後端會回讀 host 最多 90 秒(每次間隔 1 秒),只有在 host 顯示該部署的 fencing token 與 release 摘要時才認定啟用成功。啟用後的就緒檢查方式與雲端相同。

維護 epoch 與還原保護

維運作業會透過 API 擋下部署與修復。POST /private/module/edge-workers/worker/deployments 與 POST /private/module/edge-workers/company/departments/{department_id}/repairs 會回 409,detail 是純字串:

狀態部署與修復其他影響
resync epoch 進行中(或維護資料列不存在)409 edge_workers_maintenance公開流量照常。
備份圍欄 開啟中接受(202);啟用等到 fence 結束無。
還原保護開啟中409 edge_workers_restore_pending每個 Worker 都在 host 上退役,因此公開 URL 回 404 worker_not_found。後端對 host 的呼叫回 503:呼叫 Department Worker gateway is unavailable、執行期設定 Department Worker runtime config is unavailable、機密 Department Worker secrets are unavailable、存取政策 Department Worker access policy is unavailable、操作設定 Department Worker operation settings are unavailable。公開 URL 路由仍會回應。

TeamSync 雲端上永遠不會出現這些 409。

啟用附加元件

附加元件只隨 -edge 與 -full 套件包提供。在套件外層資料夾執行 ls system/scripts/setup-edge-workers-onprem.sh 確認;檔案不存在時,需要改用帶有此附加元件的套件包。啟用會重新啟動套件的服務,之後也無法再使用一鍵升級(見下方升級說明)。

cd ~/TeamSync ./system/scripts/teamsync.sh enable edge-workers # first enable: no questions; uses the defaults cd ~/TeamSync/system ./scripts/setup-edge-workers-onprem.sh # interactive: Enter enables ./scripts/setup-edge-workers-onprem.sh --apply # enable, re-apply after an upgrade, or resize ./scripts/setup-edge-workers-onprem.sh --doctor # read-only check: PASS / WARN / FAIL per line

新機器可在安裝時一併啟用:./scripts/deploy-single-node.sh ... --with-edge-workers --edge-workers-max 50 --edge-data-dir <dir>。沒有 --apply(或 --yes)且沒有終端機時,安裝程式只做預覽。成功時印出 已啟用 Edge Workers。 / Workers enabled. 附加元件已開啟時,teamsync.sh enable edge-workers 會先執行 --doctor,只有在終端機中回答 y 才會重新套用。

旗標意義
--apply啟用、升級後重新套用,或調整容量。
--yes不詢問直接啟用(隱含 --apply)。
--edge-workers-max NWorker 容量,1 到 1000 的整數(預設 50;重跑時沿用目前的值)。沒有終端機時超出範圍:--edge-workers-max 請填 1 到 1000 的整數,例如 50。 / --edge-workers-max must be an integer from 1 to 1000, e.g. 50.(以 2 結束);在終端機中會重新詢問。
--edge-data-dir DIR把 Worker 資料與 host 狀態放在 DIR/data 與 DIR/state;建議放在獨立的磁碟或分割區。
--control-subnet CIDR內部 edge_control 網路:/29 或更大的私有 IPv4 網段(預設 172.31.253.0/29)。
--extra-ca-certs PATHWorker fetch() 額外信任的 PEM 簽發者 bundle(CA:TRUE)(預設 TEAMSYNC_EXTRA_CA_CERTS);複製到 edge-workers/ca/extra-ca.pem。
--rotate-key新的 dispatch 簽章金鑰(搭配 --apply;短暫中斷)。
--disable隱藏模組、移除公開路由、把 provider 切回 cloudflare 並停止 edge 服務(搭配 --apply;資料與金鑰保留)。
--doctor唯讀健康檢查;任何一行為 FAIL 時以 1 結束(只有 WARN 時以 0 結束)。
--refresh-address同步由網站位址衍生的設定(套件變更網址時使用)。
--project-name NAMECompose 專案名稱,當堆疊是以 -p 啟動時使用。
-h、--help顯示說明。

未知選項或缺少值的旗標以 2 結束。--apply 依序執行:檢查(套件包、HTTPS HOST、健康的後端、套件自己的憑證:rotate-kit-credentials.sh --check 仍找到出廠值時拒絕)→ 只在缺少時產生金鑰與機密 → 啟動 edge-artifacts 並建立 bucket → 建立缺少的資料表並驗證 edge_worker_maintenance → 寫入後端 prod.env 區塊、啟動 edge-host 與 edge-gateway、重建 backend 與 worker → 執行一次 resync → 最後在 UI 顯示模組並加上 /edge/public/ nginx 路由。

端到端驗證:執行 --doctor 與 python3 scripts/edge-workers/edge-workers-proof.py --base-url https://<host> --username <company admin> --ca-file nginx/certs/certificate.crt(密碼取自 TEAMSYNC_PASSWORD)。

容量規劃

安裝程式依 --edge-workers-max(N)計算 edge-host 的記憶體上限:

mem_limit = 256 MiB (hostd) + 128 MiB (backup helper) + (N + 1) × 64 MiB + 512 MiB (one RSS cap)

Nmem_limit
50(預設)4160 MiB(pids_limit 13120)
61344 MiB
21088 MiB

調整容量時重跑 ./scripts/setup-edge-workers-onprem.sh --apply --edge-workers-max <larger N>:它會重新計算記憶體上限與 EDGE_HOST_MAX_WORKERS 並重建 edge-host 與 edge-gateway,因此每個 Worker 都會重新啟動,公開請求最多暫留 EDGE_HOST_HOLD_MS(預設 30 秒)。

Worker 資料與 host 狀態預設放在 Docker volume edge_host_data/edge_host_state,與 MySQL、MinIO 在同一個檔案系統(--doctor 會對此提出警告)。專用檔案系統的大小應為:預估的 Worker 資料 + 2 × 最大的 Worker + 水位線 max(10 %, 5 GiB) + 餘裕 max(1 GiB, 2 %)。

停用

./scripts/setup-edge-workers-onprem.sh --disable --apply 會隱藏模組、移除 /edge/public/ 路由、設定 EDGE_WORKERS_PROVIDER=cloudflare、重建 backend 與 worker,停止並移除 edge-host、edge-gateway 與 edge-artifacts 容器,並把附加元件從 COMPOSE_FILE 移除(每晚的備份不再包含它)。資料、金鑰與 volume 都會保留;它會印出 已停用 Edge Workers;資料與金鑰保留。 / Workers are off; data and keys are kept. 之後執行 --apply 即可重新啟用。只加 --disable 時,會先詢問(在終端機中)或只做預覽。

維運指令

Resync

resync 讓 host 只服務資料庫所記載的內容。可以安全重跑;重跑會接續同一個 epoch。

./scripts/edge-workers/resync.sh [--accept-edge-data-mismatch | --abort-diverged | --edge-absent]

這個包裝腳本在一次性的 backend 容器中執行 resync。它先取得一把鎖(同時執行第二個會失敗),開啟維護 epoch(期間部署與修復回 409 edge_workers_maintenance;公開流量照常),接著最多執行 3 輪:結清被攔下的部署、把每個存活 Worker 在 host 上的 release 收斂到資料庫的目前版本(從驗證過的產物重新上傳遺失或損壞的 release)、讓其他所有仍在服務的 Worker 退役、驗證。

旗標作用
無修復偏差,讓資料庫與 host 重新配對。
--edge-absent還原的備份沒有 Worker 資料:開啟還原保護,並讓 host 上的每個 Worker 退役。不能與 --accept-edge-data-mismatch 並用。
--accept-edge-data-mismatch結束還原保護;為每個 Worker 寫入 edge_worker.resync 稽核資料列,reason_code 為 edge_data_mismatch_accepted(租戶可見)。只在確認備份與差異後使用。
--abort-diverged對 3 輪後仍偏差的 Worker:其目前版本變成 failed(edge_host_release_lost;還原保護期間為 edge_host_resync_failed;訊息 Edge Worker release was lost during resync),Worker 變成沒有目前版本的 draft,被攔下的部署以 edge_host_resync_failed 失敗。可與上述任一旗標並用。

被攔下的部署只有在 host 證明其 token 與摘要、產物驗證通過且就緒檢查成功時才會完成;否則以 edge_worker_deleted、edge_host_resync_superseded、edge_workers_restore_pending、edge_host_resync_artifact_invalid 或 edge_host_resync_unready 失敗,由部門重新提交。每項變更都以 edge_worker.resync 稽核,actor 為 system,reason_code 為 promoted(被攔下的部署已完成)、settled_failed(被攔下的部署失敗)、edge_worker_deleted(被攔下的部署因其 Worker 已刪除而失敗)、cleared、retired、unretired、rolled_back、edge_data_held 或 edge_data_mismatch_accepted。

它只印出一行 JSON(絕不含機密):

結果輸出結束碼
已收斂{"diverged": [], "edge_data_hold": false, "epoch": "<hex>", "state": "idle"}(還原保護仍開啟時 edge_data_hold 為 true)0
未收斂{"epoch": "<hex>", "error": "edge_host_resync_diverged", "hint": "rerun resync or use --abort-diverged", "scripts": [...], "state": "active"};epoch 維持開啟1
其他失敗{"state": "active", "error": "<ExceptionClass>"}(ValueError:provider 不是地端)1
未知選項(包裝腳本)Unknown option: <arg> 與修復指令 ./scripts/edge-workers/resync.sh --help2
Docker 無法使用(包裝腳本)訊息1

備份圍欄

scripts/backup.sh 會在備份期間暫停部署啟用(fence),分成 begin 與 end 兩個步驟;維運人員通常不需要直接執行。

步驟行為輸出
beginresync epoch 進行中、還原保護開啟中或已記錄 fence 時拒絕。否則把 host 的 fence 設到現在 + EDGE_BACKUP_FENCE_MAX 秒(預設 7200,允許 1–86400),再把 fence 記錄到資料庫。{"edge": "fenced", "until": <unix s>},或 {"edge": "absent", "reason": "edge_workers_maintenance"}/"edge_workers_restore_pending"
end必須等 host 確認 fence 結束,才清除資料庫中的 fence;--abandon 會對 host 重試最多 30 秒。接著重新發布被延後的部署。{"edge": "complete", "held": true};fence 已過期、被 resync 清除或隨 edge-host 重新啟動而遺失時為 {"edge": "absent", "held": false}

結束碼:fenced/complete 為 0,absent 為 2,任何錯誤為 1({"edge": "absent", "error": "<ExceptionClass>"})。fence 期間,部署請求照樣接受並等待(edge_host_fenced);fence 結束後立即啟用。fence 只存在 host 的記憶體中:後端每 15 秒的調節會清除 host 已不再回報的資料庫 fence。

edge-hostctl

在容器內執行,例如 docker compose exec edge-host edge-hostctl status。<script> 是 Worker 的 script 名稱 dw-<48 hex>。

指令輸出結束碼
health{healthy, bootComplete, degraded};degraded 可能列出 edge_host_disk_low、edge_host_memory_headroom_low、edge_host_capacity_exceeded。也是容器的 Docker 健康檢查。開機完成且 fallback 行程在執行時為 0;否則或超過 10 秒為 1
status每個 Worker 的 JSON(狀態、pid、重啟次數、儲存、隔離)、維護、fence、暫留的請求、磁碟、記憶體、備份與 hostd0
backup-worker <script> [--same-filesystem]stdout 輸出經驗證的 Worker 儲存 tar,stderr 輸出 JSON 結果;失敗代碼 edge_host_backup_unknown_script、edge_host_backup_measure_failed、edge_host_backup_precheck_failed、edge_host_backup_copy_aborted、edge_host_backup_copy_failed、edge_host_backup_copy_invalid0/1
backup-statestdout 輸出一致的 host 狀態 tar0/1
set-budget <script> <size>設定該 Worker 的儲存預算(2GiB、512MiB 或位元組數),並恢復現在已容得下的預算停止;印出 {script, budget, usage, resumed}0
resume <script>解除水位線或儲存停止。拒絕時印出 refused: the data filesystem is below its watermark 或 refused: the Worker is over its budget; raise it with set-budget0;拒絕或未恢復時為 1
clear-quarantine <script>結束隔離並重新啟動該 Worker;印出 {script, cleared}0

不帶指令時印出用法並以 2 結束;未知指令以 2 結束。指令失敗時(例如 script 名稱或大小無效)印出 error: <reason> 並以 1 結束。

備份與還原

./scripts/backup.sh(以及每晚的排程)會自動加上 Edge 部分:edge/workers/<script>.tar、edge/state.tar、edge/artifacts.tar.gz 與 edge/config.env(權限 0600)。順序:暫停啟用(fence)→ MySQL、Redis、Qdrant、MinIO → 在服務中逐一複製每個 Worker,再複製 host 狀態 → 結束 fence → 產物與設定。manifest 記錄 "edge": "complete",或附原因(記於 edge_reason)的 "edge": "absent"(例如 edge_workers_maintenance、edge_host_backup_precheck_failed、edge_host_backup_copy_aborted、fence_not_held、edge_config_incomplete)。Edge 的問題絕不會讓套件本身的備份消失:該組備份會在缺少 Edge 部分的情況下發布,backup.sh 在發布後以 2 結束。

有附加元件時,./scripts/restore.sh <version> 會先驗證每個選取的封存檔,停止 backend、worker、edge-gateway、edge-host 與 edge-artifacts,還原後啟動 edge 服務、執行 resync,並一律重新啟動 backend 與 worker。只有 manifest 寫明 edge: complete 的備份組才會還原 Edge volume。--only edge-workers 還原完整備份組的 host 狀態與 Worker 資料;--only edge-artifacts 還原產物儲存。還原的 MySQL 若沒有對應的 Edge 部分(edge: absent 的備份組、啟用附加元件前的備份組,或 --only mysql),會執行 resync --edge-absent:每個 Worker 都在還原保護下維持退役,直到還原完整的備份組,或維運人員執行 --accept-edge-data-mismatch(--only edge-workers 不會改變還原保護)。resync 未收斂時,套件仍維持運作,restore.sh 以 3 結束。

升級、金鑰輪替與網址變更

  • 升級。 有附加元件的機器上,一鍵升級會停下來;請依套件的手動升級指南進行。其中 Edge Workers 步驟:新套件必須帶有附加元件;以 cp -a "$NEW/edge-workers/." edge-workers/ 從新套件複製 edge-workers/(保留 *.env 與 ca/extra-ca.pem),再執行 ./scripts/setup-edge-workers-onprem.sh --apply 與 --doctor。金鑰與資料都會保留並執行一次 resync;新的 workerd 版本會重新啟動每個 Worker。
  • 金鑰輪替。 ./scripts/setup-edge-workers-onprem.sh --apply --rotate-key 建立新的 Ed25519 dispatch 金鑰,並重建 edge-host、backend 與 worker;由 resync 證明新金鑰可用。Worker 呼叫會失敗幾秒。
  • 網址變更。 變更套件的網站位址時,會以 --refresh-address 重跑安裝程式,把 EDGE_WORKERS_PUBLIC_BASE_URL 改寫為新位址 + /edge(手動設定的值會保留)。公開 URL 隨之改變。

退役與資料保留

部門刪除時,provider 先清除該 Worker 的執行期機密與服務帳號憑證,再通知 host 讓該 Worker 退役;host 會先記錄退役,再停止行程。若無法通知 host,後端的 host 調節(每個 API replica 每 15 秒)會重試。同一個調節也會讓 host 上任何在資料庫中沒有存活 Worker 的已服務 Worker 退役(也涵蓋公司硬刪除),但只在資料庫與 host 已配對時(沒有 resync epoch,且 host 最後一次 resync 的 epoch 相符);未配對時什麼都不退役,並記錄 edge_host_unpaired。公開 URL 會在刪除後約一分鐘內回 404 worker_not_found,仍在佇列中的該 Worker 部署則以 edge_host_script_retired 失敗。與 provider 無關的流程見退役。

與雲端不同,地端會保留已退役 Worker 的資料:host 永遠不會清除它。每個 Worker 的 host 保留目前啟用的 release 與前兩個(加上最後一次啟用嘗試的 release,以及待完成切換仍指名的 release);更舊的 release 會被修剪。Worker 儲存只有一份:還原點就是最後一次備份。--disable --apply 會保留資料與金鑰。

產物儲存

在地端,專案壓縮檔與 bundle 存放在專用的 edge-artifacts 服務,而不是 R2:以 S3 用戶端連到 http://edge-artifacts:9000,使用 path-style 定址、區域 us-east-1、bucket edge-worker-artifacts 與 EDGE_WORKERS_ARTIFACTS_* 憑證(缺少值時以 dedicated on-prem Edge Worker artifact store is not configured 失敗)。它不對外公開任何連接埠,也不在套件公開的 /s3/ 代理之後;絕不要把它放到那裡。

環境變數

所有值都由安裝程式寫入;產生的金鑰與機密永遠不會印出。後端的其他設定見環境變數。

後端(prod.env)。 在地端,後端永遠不讀取 EDGE_WORKERS_CLOUDFLARE_*、EDGE_WORKERS_DISPATCH_ORIGIN 或 EDGE_WORKERS_R2_*。

變數值
EDGE_WORKERS_PROVIDERonprem(未設定或空值 = cloudflare)
EDGE_WORKERS_ONPREM_GATEWAY_URL必須是 http://edge-gateway:8080
EDGE_WORKERS_ONPREM_SCOPE_ID恰好 12 個小寫 hex 字元;部署範圍為 onprem:<scope id>
EDGE_WORKERS_HOST_AUDIENCEteamsync-edge-host(預設)
EDGE_WORKERS_DISPATCH_PRIVATE_KEYEd25519 簽章金鑰(機密)
EDGE_WORKERS_DISPATCH_KEY_ID金鑰 id
EDGE_WORKERS_DISPATCH_AUDIENCEteamsync-department-workers
EDGE_WORKERS_DISPATCH_ISSUERteamsync-backend
EDGE_WORKERS_ARTIFACTS_ENDPOINT_URL必須是 http://edge-artifacts:9000
EDGE_WORKERS_ARTIFACTS_BUCKETedge-worker-artifacts
EDGE_WORKERS_ARTIFACTS_ACCESS_KEY_ID、EDGE_WORKERS_ARTIFACTS_SECRET_ACCESS_KEY產物儲存憑證(機密)
EDGE_WORKERS_PUBLIC_BASE_URLhttps://<kit host>/edge(HTTPS,不含帳密、query 或 fragment)
EDGE_BACKUP_FENCE_MAX備份圍欄 長度(秒):預設 7200,允許 1–86400

缺少或格式錯誤的值會以 edge_workers_provider_invalid 失敗(Edge Worker on-prem credentials are incomplete、Edge Worker on-prem scope is invalid、EDGE_WORKERS_PUBLIC_BASE_URL must be an HTTPS /edge base、<NAME> must use the kit's internal service)。

Edge host(edge-workers.env 與 compose)。 任何無效的整數或大小都會讓 hostd 在啟動時停止,但有三個值 hostd 不檢查、直接傳遞:無效的 EDGE_HOST_INVOCATION_TIMEOUT_MS 退回 30000;無效的 EDGE_WORKER_CPU_MS(1–30000)或 EDGE_WORKER_SUBREQUESTS(1–1000)會讓公開通道請求回 503 dispatcher_unavailable。

變數預設(範圍)
EDGE_WORKER_ASSERTION_PUBLIC_JWK必填(dispatch 公鑰)
EDGE_HOST_CONTROL_ADDRESS、EDGE_HOST_RELAY_ADDRESS、EDGE_HOST_CONTROL_SUBNET必填;套件預設 172.31.253.3、172.31.253.2、172.31.253.0/29
EDGE_WORKER_ASSERTION_ISSUER/EDGE_WORKER_ASSERTION_AUDIENCE/EDGE_WORKERS_HOST_AUDIENCEteamsync-backend/teamsync-department-workers/teamsync-edge-host
EDGE_WORKER_CPU_MS50(會解析,但地端不強制)
EDGE_WORKER_SUBREQUESTS500(公開通道)
EDGE_HOST_INVOCATION_TIMEOUT_MS30000(最大 300000)
EDGE_HOST_HOLD_MS30000(1000–120000)
EDGE_HOST_HOLD_MAX_PER_SCRIPT256(1–10000)
EDGE_HOST_HOLD_MAX_REQUEST_BYTES/EDGE_HOST_HOLD_MAX_SCRIPT_BYTES/EDGE_HOST_HOLD_MAX_TOTAL_BYTES1 MiB(最大 64 MiB)/16 MiB(最大 1024 MiB)/64 MiB(最大 1024 MiB)
EDGE_HOST_WORKER_HEAP_MB128(16–4096)
EDGE_HOST_WORKER_RSS_MB512(32–65536)
EDGE_HOST_WORKER_STORAGE_GB2(GiB,或 512MiB 這類大小)
EDGE_HOST_WORKER_NPROC/EDGE_HOST_WORKER_NOFILE256(16–65536)/4096(64–1048576)
EDGE_HOST_MAX_WORKERS50(依 --edge-workers-max 寫入;hostd 接受 1–100000)
EDGE_HOST_DISK_WATERMARK_BYTES未設定 = 資料檔案系統的 max(10 %, 5 GiB)
EDGE_HOST_BACKUP_MARGIN_BYTES未設定 = max(1 GiB, 2 %)
EDGE_HOST_LOG_LINES_PER_SECOND/EDGE_HOST_LOG_BYTES_PER_SECOND200/256 KiB
EDGE_HOST_EXTRA_CA_FILE/etc/edge-host/ca/extra-ca.pem

套件 .env。 EDGE_WORKERS_CONTROL_SUBNET、EDGE_WORKERS_CONTROL_HOST_IP、EDGE_WORKERS_CONTROL_RELAY_IP、EDGE_HOST_MEM_LIMIT(預設 4160m)、EDGE_HOST_PIDS_LIMIT(預設 13120)、EDGE_HOST_STATE_SOURCE、EDGE_HOST_DATA_SOURCE(預設為具名 volume)。

Relay(edge-workers/relay.env)。 EDGE_RELAY_SECRET 必須至少 32 個 URL 安全字元;否則 relay 對每個請求都回純文字 503。

Last updated on