Vercel Daemons 新增服務綁定與存活檢查,卡住就自動重啟

Vercel 於 10 月 30 日為 Public Beta 的 Daemons 新增服務綁定與 HTTP 存活檢查,背景工作可呼叫同次部署的私有服務,卡住的程序連續三次檢查失敗後由平台重啟。官方文件另載明綁定釘住啟動時的部署、存活失敗走 SIGKILL 不吃寬限期,Hobby 每月 420 GB-小時記憶體額度約只夠 2 GiB 常駐九天。

用 AI 摘要這篇文章:

10 月 30 日,Vercel 給半個月前才進入 Public Beta 的 Daemons 補上兩件裝備:背景工作可以透過服務綁定呼叫同一次部署裡的私有服務,也可以掛 HTTP 存活檢查,讓平台抓出「還在執行卻已經卡住」的程序強制重啟。兩條 changelog 分別由 Gal Schlezinger 與 Nik Sidnev 署名,頁面日期都是 30 Oct 2026;官方開發者帳號的公告推文發在台北時間 23 時 49 分,執行長 Guillermo Rauch 八分鐘後補一句「Vercelnetes or V8S for short」,把那個影子的出處自己點破了。

這句玩笑其實是最快的入門指引。打開官方文件,vercel.json 裡的新欄位叫 livenessProbe,底下是 httpGet 的 port 與 path,旁邊站著 initialDelaySeconds、periodSeconds、timeoutSeconds、failureThreshold;連「HTTP 200 到 399 算成功、其餘算失敗」的定義,都跟 Kubernetes 探針文件相同。碰過 Kubernetes 的人幾乎不必重學詞彙,真正要重學的是語意:兩個原語進到 Vercel 之後被平台改寫了兩處,而且都改在出事時才看得到的位置,一處是服務綁定釘死在啟動它的那次部署,另一處是存活檢查失敗的後果是不吃寬限期的立即強制終止。

下面先拆這兩項能力各做了什麼,再回頭看這兩處改寫為什麼值得在意。

Vercel 官方 changelog 截圖,文章標題 Add liveness checks to your Daemons,署名 Gal Schlezinger、日期 30 Oct 2026,內容示範健康端點程式碼與 vercel.json 的 livenessProbe 設定,並說明平台會定期請求端點、檢查失敗時重啟容器Pin
存活檢查的官方公告:健康端點由工作程式自己提供,livenessProbe 指向它的 port 與 path。(來源:Vercel changelog)

詞彙照搬,語意改寫:一張表看差異

面向KubernetesVercel Daemons
探針由誰發話節點上的 kubelet 對容器發話從執行個體內部發出
探測方式exec、HTTP、TCP、gRPC 四種僅 HTTP GET
服務尋址Service 名稱跨版本穩定綁定釘住啟動時的那次部署
存活失敗的終止kubelet 殺掉容器並重啟立即 SIGKILL,不遵循寬限期

欄位名同形不代表行為同義。Kubernetes 的探針由節點上的 kubelet 發話,等於叢集代替你問容器;Vercel 的檢查從執行個體內部發出,等於程序自己回報。這個方向差異的後面兩節會展開:它讓 daemon 掛了健康端點也不會得到對外網址,也讓換版時的服務尋址走向跟 Service 抽象剛好相反的設計。

服務綁定:私有後端的地址,由平台塞進環境變數

Daemons 是 Vercel 在 10 月 15 日開放 Public Beta 的常駐程式(daemon)功能:用 Dockerfile 或 Containerfile 打包映像檔,平台在指定區域維持你設定的執行個體(instance,同一份程式的一份運行副本)數量,程序(process)持續從佇列或工作流引擎拉工作來做,沒有對外入口。beta 公告列的典型成員是佇列消費者、Temporal 或 Cadence 這類工作流 worker、自架的 CI runner。

這類程式經常需要回頭呼叫自己專案裡的其他服務,例如拉到一筆工作後,向私有 API 要資料。順帶一提生命週期的兩個端點:建置時映像檔會推到 Vercel Container Registry,存放庫名稱是 daemon.加 daemon 名稱;執行個體的 stdout 與 stderr 會轉送到專案的日誌頁,觀察不需要另外接管。10 月 30 日之前,這段連線要自己張羅:地址放哪、認證怎麼帶、要不要把服務開到公網。服務綁定把這三件事收走:在 daemon 設定裡宣告目標服務與接收地址的環境變數名稱,平台把服務網址放進變數,內部路由、認證與 TLS 加密連線都由 Vercel 處理,目標服務可以完全不對外公開。

[services.api]
root = "api/"
entrypoint = "main:app"

[daemons.worker]
root = "worker/"
entrypoint = "Dockerfile"
instances = { iad1 = 1 }

[[daemons.worker.bindings]]
type = "service"
service = "api"
format = "url"
env = "API_URL"

worker 端讀 API_URL,用一般的 fetch 呼叫,不必把主機名稱寫死在程式裡。

方向是單行的。changelog 明講:daemon 可以綁服務,服務不能反過來綁 daemon;limits 頁再補一條,daemon 也不能當服務綁定或 rewrite 的目標。背景工作仍然是純粹的消費者,要對外收請求的程式,平台指向 Services 或 Functions。內部可達也不等於應用層授權:訂單服務願意接 worker 的呼叫,跟這個 worker 能改哪些欄位,是兩件事,後者由後端自己的規則決定。

釘在啟動那次部署:換版瞬間新舊並存

綁定的語意裡藏著一條容易被略過的規則:每個執行個體的綁定,指向啟動它的那次部署。新的部署升為正式版、或團隊復原到舊版時,平台會換掉相應的背景程式並停止前一版,但在舊個體停止之前,它呼叫的一直是舊部署裡的服務。

跟 Kubernetes 的 Service 抽象對照,差異是刻意設計的:Service 的名稱跨版本穩定,Pod 換代後照著名字就拿到新後端;Vercel 的綁定剛好反向,讓工作中的背景程式對後端的依賴整組跟著舊部署走。好處是舊工作不會突然連到新後端吃下不相容的介面,代價是換版瞬間新舊兩代 worker 連的是兩個版本的後端,佇列訊息的格式相容與跨版本資料遷移,都還是應用程式自己的責任。官方文件給的方向很一致:把工作設計成可以中途被殺掉再跑一次。

另外要記得容器映像檔、指令與環境變數都屬於部署的一部分,改這些內容要走一次新的正式部署,不能指望線上的執行個體熱更新。可以不部署就動的只有執行個體數量,而且從 dashboard 或 CLI 蓋過去的數量設定會跨部署留存,直到清除為止。

存活檢查:量的是「還能不能前進」,不是「有沒有做完」

預設行為下,Vercel 只在程序退出或崩潰時重啟。程序掛死在連線上、繞不出去的迴圈裡,這種活著卻不動的狀態,退出訊號永遠等不到。livenessProbe 補的就是這一塊:平台定期對執行個體發 HTTP GET,連續失敗到門檻就重啟容器。

{
  "daemons": {
    "worker": {
      "root": "worker/",
      "entrypoint": "Dockerfile",
      "instances": { "iad1": 1 },
      "livenessProbe": {
        "httpGet": { "port": 1234, "path": "/health" },
        "initialDelaySeconds": 5
      }
    }
  }
}

判定規則逐條列在文件裡。200 到 399 都算成功,重導向不跟隨,但 3xx 本身也算成功,所以健康端點不能只是一個轉去登入頁的 redirect;連線錯誤、逾時、任何其他狀態碼算失敗。一次成功就把累積失敗歸零,連續 failureThreshold 次失敗才觸發重啟。預設值是每 10 秒查一次、逾時 1 秒、連續 3 次失敗觸發;官方的時間線範例是:容器啟動 5 秒後首次檢查通過,之後每 10 秒一次,假設程式在約 605 秒時卡死,605、615、625 秒三次都失敗,容器約在 625 秒被終止。

Vercel 官方文件 Health checks and restarts 段落截圖,包含 livenessProbe 的 vercel.json 與 vercel.toml 設定範例,以及成功定義說明:HTTP 200 到 399 算成功、重導向不跟隨但 3xx 也算成功,連線錯誤、逾時或其他狀態碼算失敗Pin
官方文件的判定規則:200 到 399 算成功、3xx 不跟隨也算成功,一次成功就把失敗計數歸零。(來源:Vercel 文件)

時程還有兩條規則:每個執行個體分開探測,時程在每次重啟後從頭算;改過的 livenessProbe 只套用在它部署之後啟動的執行個體,線上舊個體照舊規則跑。

兩個工程細節比數字更值得記。檢查從執行個體內部發出,這代表 daemon 不會因為掛了健康端點就拿到對外網址,流量政策一寸不讓;同時健康端點必須由工作迴圈同一個程序提供,文件特別警告,只加 livenessProbe 設定卻沒有真的起 HTTP 端點,每次檢查都會失敗,反而掉進反覆重啟。端點本身要輕,而且反映的是「這個程序還能不能前進」,不是下游依賴的總體檢查:資料庫短暫變慢就把所有 worker 同時判死,對資料庫沒有幫助。

還有就是別對它期待太多。檢查結果只分 pending、passing、failing 三種狀態,它證明程序依設定能繼續,不證明工作已經交付。報告產了沒、資料寫進去了沒,要看任務自己的完成紀錄。

出事的收場:SIGKILL 不等清場

平台停止一個 daemon 有兩條路,走的訊號不一樣。正常替換,推出新版、調降執行個體數、移除 daemon,平台送 SIGTERM,預設等 30 秒讓程序停止接新工作、清完手上的資源,這段寬限期可以用 terminationGracePeriodSeconds 調成 0 到 3600 秒。存活檢查失敗觸發的重啟則是立即 SIGKILL,文件明寫不遵循寬限期。

這個差別直接決定程式怎麼寫:把保存進度寫在 SIGTERM 處理器裡的程式,健康失敗時那段程式碼根本沒有機會執行。進度保存要放在平常的路徑上,而不是收尾的路徑上。

重啟本身也有節流。退避從 1 秒起算、每次翻倍、上限 5 分鐘;單次運行滿 5 分鐘就重置退避;如果 10 分鐘內每次都活不過 5 分鐘,平台不再重啟同一個執行個體,直接換一個新的。這套機制擋的是無止盡的快速崩潰循環,擋不了程式本身的缺陷。配套要求寫在文件裡:工作要冪等,同一筆工作跑兩次不該產生兩份不同的結果;佇列訊息要在處理完成後才確認,太早確認,失敗後就少了重試的機會,晚點確認,就要能辨認重複送來的同一筆工作。

Hobby 的算術:等待不花 CPU,活著就花記憶體

各方案都吃得到 beta,但額度結構值得單獨看,因為它決定誰真的用得起常駐。Hobby 每月內含 5 個 Active CPU 小時與 420 GB-小時的配置記憶體。Active CPU 只在程式碼執行時計,長時間空等工作不計;文件還提醒,HTTPS 的加解密運算也算 CPU,看起來在等的程式未必真的零消耗。記憶體是另一本帳:執行個體每活一小時就計一小時,跟忙不忙無關。

官方給的換算例子:一個 2 GiB 的執行個體不停跑,大約 9 天就把 420 GB-小時用完。用完之後,整個團隊的 daemons 停到下一個 UTC 月初,或者升級到 Pro。換句話說,Hobby 拿得到這個功能,但拿不到一整月的常駐,記憶體額度約只夠三分之一個月。

Vercel 官方文件 Default quotas 表格截圖,列出 Hobby 方案每月 5 個 Active CPU 小時與 420 GB-小時配置記憶體、Pro 方案 16 vCPU 與 32 GiB 同時運行上限、Enterprise 另議,下方說明 2 GiB 執行個體連續運行約 9 天達到 420 GB-小時Pin
各方案的預設額度:Hobby 的 420 GB-小時,2 GiB 執行個體連續跑約 9 天就見底。(來源:Vercel 文件)
方案可用尺寸每月內含超出後
Hobby1 或 2 GiB(1 vCPU)5 Active CPU 小時+420 GB-小時不計費,額度用罄即停到下個 UTC 月初
Pro1 到 8 GiB定價頁未單列內含額度CPU 每小時 0.128 美元起、記憶體每 GB-小時 0.0212 美元起
Enterprise全部尺寸另議另議

Pro 與 Enterprise 依 Active CPU 與配置記憶體兩軸計費。拿定價頁費率換算,一個 2 GiB 執行個體跑滿整月約 1,440 GB-小時,以每 GB-小時 0.0212 美元計,光記憶體一項約 31 美元,閒置不等於免費。規模上限畫在同一份文件裡:每個 daemon 每區域最多 100 個執行個體、每個專案最多 100 個 daemons、每個專案環境最多 50 個執行個體,超量時平台先滿足較舊的 daemon,吃不滿的會在日誌記錯誤。

Beta 的圍欄:只跑正式環境,測試要在本機先做完

limits 頁的不支援清單替 beta 階段畫出圍欄:只在正式環境跑,沒有 preview 部署;沒有自動縮放,執行個體數量手動設;沒有持久本機儲存,狀態要放資料庫或 Blob 這類服務;不收外部 HTTP 或 TCP 流量;vercel dev 不會執行 daemon,設定檔裡有 daemons 時它印警告然後跑其餘部分,本機測試要用 Docker 自己起容器;執行環境只有 Linux amd64 一種架構;專案的根目錄若設在子資料夾,目前還不能加 daemons。試驗流程跟一般網站的 preview 部署完全是兩回事,這大概是最容易踩到的營運差異。

至於這跟 AI 的關係,Vercel 自己的文件給了定位:Agent Frameworks 頁把 Daemons 列為代理(AI agent)基礎服務的一員,與 Functions、AI Gateway、Sandbox、Passport 並列,角色是持續從佇列或工作流引擎拉工作的背景 worker。代理跑長任務需要有人承接等待與重試,常駐程序就是那個承接層。同一條產品線上,AI Gateway 十月底才把模型選擇收進 Virtual Models 的共用名稱,市集憑證也剛換到短效身分;Daemons 補上綁定與存活檢查後,這套給代理用的地基又厚了一層。代理的工作負載若已經長到要排隊等設備,裝置租約是另一種正在出現的解法。

現在值得動手的人,與還該等的訊號

適合現在就接上的,是已經在 Vercel 正式環境跑佇列消費者或工作流 worker、而且後端本來就要自己張羅認證與地址的團隊:綁定收走的正是那塊最容易出錯的膠水,存活檢查補上崩潰之外的另一種死亡形式。想在 Hobby 上試水溫,先想清楚記憶體額度只夠九天,把它當評估環境而不是長期常駐。還沒把工作冪等做好的程式碼,先補那件事再掛探針,否則存活檢查只是把缺陷用更高的頻率重播。

未定案的部分也該列清楚:preview 部署、自動縮放、持久儲存都不在 beta 支援範圍,官方沒有給時間表;定價頁的 daemon 費率掛著 beta 字樣,數字可能隨階段調整。Public Beta 從 10 月 15 日到月底已經兩批更新,間隔不到三週,之後要引用任何數字,先回官方文件與定價頁看當下的值。

Sliven 褚崇名
Sliven 褚崇名

每日分享科技新知、免費資源以及 WordPress、虛擬主機相關主題,任何問題歡迎在科技月球下方留言,或是發送 Email 至 [email protected] 與我聯繫。

文章: 2246

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


Share to...