Vercel Daemons 新增服務綁定與存活檢查:背景工作連得上,卡住後也能重啟?

Vercel Daemons 新增私有服務綁定與 HTTP 存活檢查。解析部署版本、正常停止與強制重啟、冪等工作、Hobby 常駐記憶體配額及 beta 限制。

Share
Vercel Daemons 官方封面,以文字宣布背景程序可透過 bindings 呼叫服務。
Vercel 的 Daemons 官方封面宣布服務綁定更新;同日存活檢查則用來發現仍在執行卻無法工作的程序。 圖片來源:官方原文。

Vercel Daemons 處理的是持續留在後台工作的程式,但程式一直開著,不代表一直有在工作。像是拉取佇列、處理報表或接收代理任務,一旦連線斷了、迴圈卡住,外表仍看得到程序,實際工作卻可能停下。

Vercel 在 10 月 30 日加入兩項能力:背景程序可透過服務綁定呼叫同次部署的私有服務,以及用 HTTP 存活檢查,找出仍在執行卻不健康的程序。

Daemon 可以理解為長時間留在後台、反覆取工作來做的程式。這次新增的不是 AI 模型,而是讓這類程式更容易連上自己的後端,並在失去工作能力時由平台重啟。

服務綁定把私有服務網址交給背景程式,內部路由、認證與加密連線由平台處理。存活檢查則定期問健康端點,連續失敗才觸發恢復,兩者分別處理連線與程序是否還能前進。

不過,自動重啟不保證任務只做一次,也不會替應用程式保存尚未寫下的進度。存活檢查觸發的強制終止,甚至和正常部署時留下清理時間的流程不同。

因此,導入時要把後端版本、健康訊號與重試方式一起想清楚。背景程序有了可管理的入口和恢復機制,任務本身仍要能承受中途停止與再次執行。

Vercel Daemons 服務綁定,讓背景程式呼叫私有後端

原本要讓背景工作連上後端,常得處理網址與存取認證。服務綁定讓呼叫者在設定中指出目標服務,再由平台把產生的網址放進指定環境變數。

環境變數可以理解為程式啟動時取得的一組設定值。背景程式讀取它,再以一般 HTTP 請求呼叫後端,不需要把固定的公開主機名稱寫死在程式裡。

官方例子讓 worker 綁定 api 服務,透過 API_URL 取得網址,再請求下一項工作。名稱本身只是範例,重點是呼叫者與被呼叫服務的關係明確寫在設定中。

平台會處理內部路由、認證與 TLS 加密連線,目標服務可以維持不對外公開。但內部可達不等於已完成應用層授權,後端仍要依自己的資料與業務規則檢查權限。

假設背景程式能連進訂單服務,仍不代表它應該修改每一位客戶的任何欄位。綁定解決的是服務之間的連線入口,哪些操作可執行,仍需由應用程式決定。

方向也有邊界:daemon 可以綁定服務,服務不能反過來把 daemon 當成綁定目標。這次更新沒有把背景工作變成一般對外接受 HTTP 請求的伺服器。

因此,佇列消費者可以主動取工作,再呼叫自己的私有後端。若應用需要接受外部請求,官方仍指向 Services 或 Functions 等適合回應請求的入口。

連線設定集中管理後,下一個問題是它究竟連到哪一版後端。對長時間運行的工作,這比只確認網址能不能打開更重要。

Vercel Daemons 官方封面,以文字宣布背景程序可透過 bindings 呼叫服務。
Vercel 的 Daemons 官方封面宣布服務綁定更新;同日存活檢查則用來發現仍在執行卻無法工作的程序。 圖片來源:官方原文。

部署換版時,舊工作仍連到啟動它的版本

服務綁定固定的是啟動該背景執行個體的那次部署。執行個體就是同一份背景程式的一份運行副本,可以依設定在特定區域維持指定數量。

當新的部署被提升為正式版本,或團隊回復到先前版本,平台會推出相應背景程式,並停止前一版。舊執行個體尚未停止前,仍呼叫啟動它的那次部署裡的服務。

這個安排讓舊工作不會只因正式網址換版,就突然連到另一版私有後端。但它沒有替應用程式處理不同版本之間所有資料格式差異。

假設新版改了工作欄位名稱,而外部佇列裡仍有舊格式工作,綁定只能讓程式知道要呼叫哪個服務,不能自動把訊息轉換成新版需要的內容。

因此,部署規畫仍應包含佇列訊息與後端資料的相容性。若工作可以跨越一次換版,就要知道舊工作最後由誰完成、結果寫到哪裡,以及新程式如何辨認已完成內容。

這也說明為什麼背景程序不能只依賴記憶體裡的暫存狀態。平台可以換掉執行個體,但應用程式需要追蹤的業務進度,應另有能在重啟後讀取的位置。

容器映像、命令與環境變數也屬於部署的一部分。要修改這些內容,需要建立新的正式部署,不能假設已運行的舊個體會立刻換成所有新設定。

版本對齊能減少混用,但任務資料是否相容仍要由程式設計負責。把部署看成一次工作交接,才比較容易找出長任務可能在哪裡中斷。

存活檢查看的是還能不能前進,不是有沒有程序

一個程序還在執行,可能只是卡在連線或失去工作能力的迴圈裡。原本只在退出或崩潰時重啟,未必能發現這種「還活著卻不工作」的狀態。

新增的 HTTP 存活檢查,要求背景程式提供一個輕量健康端點。端點可以理解為專門回覆狀態的一個網址路徑,平台定期向它送出 GET 請求,再依回應判斷。

官方文件要求健康端點與工作迴圈由同一個程序提供。若只新增檢查設定,卻沒有真的啟動對應的 HTTP 端點,每次檢查都會失敗,反而造成反覆重啟。

回應成功,不等於背景任務已完成

狀態碼二百到三百九十九都算檢查成功。重新導向不會被跟隨,但三百系列回應本身仍算成功,因此端點不應只是把請求轉去登入頁,卻讓人誤以為它已驗證實際工作能力。

連線錯誤、逾時或其他狀態碼則算失敗。平台以連續失敗次數決定何時重啟,一次成功會清掉累積的失敗計數,不是每次偶發錯誤都立刻殺掉程序。

文件預設檢查週期為十秒、逾時一秒、連續三次失敗觸發重啟。起始等待時間與其他欄位可以配置,實際恢復時點還受檢查排程影響,不能把數字簡化成固定幾秒保證復原。

健康端點應反映程序能否繼續前進,而不是把每一項下游服務的健康都直接綁進來。若資料庫短暫變慢,所有工作程式同時被殺掉,未必能改善資料庫問題。

例如工作迴圈已失去必要連線、也無法恢復時,可以回報不健康。若只是暫時沒有新工作,則不應單憑佇列空了就判定故障,否則正常等待也會被當成需要重啟。

健康檢查解決的是恢復機制的訊號,不會證明報表已產生、資料已寫入或使用者已收到結果。要確認交付,還得讀取任務本身的完成狀態。

正常停止與健康失敗,留下的清理時間不同

部署換版時能做的清理,不能直接套到存活檢查失敗的情況。這兩條終止路徑,是背景工作設計最需要分清的邊界之一。

一般推出新版本、減少執行個體或移除 daemon 時,平台送出 SIGTERM 停止訊號。程式應停止接受新工作,再整理正在處理的資源,預設有三十秒時間。

這段停止寬限可設定為零至三千六百秒,但設定較長並不代表執行個體永遠不會以其他方式停止。它描述的是正常停止流程,不能替代持續保存重要進度。

存活檢查觸發重啟時則會立即送出 SIGKILL,也就是強制終止,不遵循那段寬限。若把保存狀態只放在正常結束的處理程式裡,就可能在健康失敗時來不及執行。

冪等工作,讓再次執行不重複造成結果

官方因此提醒工作要能安全重試。冪等可以理解為同一項工作重做,不會額外產生一份不同的業務結果,例如用工作識別碼辨認是否已經寫入報表紀錄。

假設程式已寫好結果,卻在回覆佇列前被終止,訊息可能再次出現。應用程式需要辨認既有結果,再決定如何完成確認,不能只期待平台知道剛才做到哪一步。

文件也建議完成處理後才確認佇列訊息。確認太早,失敗後可能沒有機會重試。確認較晚,則更需要處理重複執行,兩者都和任務資料設計有關。

重啟本身有等待退避,從一秒開始倍增,最多五分鐘。一次運行至少五分鐘會重設等待,若十分鐘內反覆短時間運行,平台會改以新執行個體取代。

這些機制能減少無止境快速重啟,但不能把有缺陷的程式自動修好。因為停止方式可能不同,進度保存與重複執行的設計必須在平時就成立。

Public Beta 的範圍,還不是完整常駐主機

Vercel Daemons 在各方案提供公開測試,仍有部署與資源限制。Beta 期間只在正式環境運行,不支援預覽部署,所以試驗方式需要和一般預覽網站分開安排。

背景工作以 Dockerfile 或 Containerfile 打包,執行環境為 Linux amd64。vercel dev 目前不會直接運行 daemon,官方建議用容器在本機測試,不能把開發伺服器啟動當成背景程序也已啟動。

目前也沒有自動擴縮與持久本機儲存。執行個體數由設定或管理入口調整,需要長期保存的狀態則應放到資料庫或合適的儲存服務。

外部 HTTP 或 TCP 流量也不支援。存活檢查雖然使用 HTTP,卻是平台從執行個體內部進行的檢查,不能因此推論程式已取得公開網址或一般網路伺服器能力。

Hobby 的每月額度包括五個有效 CPU 小時,以及四百二十 GB 小時的配置記憶體。有效 CPU 計的是程式實際執行所花的處理器時間,單純等待工作不會以整段運行時間計入。

記憶體則不同,只要執行個體仍在運行,就持續累積使用量。官方以一個二 GiB 個體不停運行為例,大約九天就會達到四百二十 GB 小時,所以不能把大多數時間在等待理解成整月免費常駐。

達到 Hobby 任一月額度後,團隊的背景程序會停止,直到下一個 UTC 月份開始,或升級 Pro。Pro、Enterprise 則依有效 CPU 與配置記憶體計費,仍須看實際方案費率。

先確認常駐記憶體與工作負載,再決定執行個體數量,才不會讓等待的成本被忽略。平台能管理程序,不代表每種長時間工作的成本結構都一樣。

把連線、健康與任務結果分開驗證

要判斷更新是否解決問題,可以先分清三個層次。服務綁定確認程式能找到並呼叫指定後端,存活檢查確認程序是否仍有工作能力,業務狀態才確認結果是否交付。

假設一個背景程序從佇列取出代理產生的報表工作,成功呼叫私有資料服務,只能證明連線走通。健康端點一直回成功,也只能說程式依設定判定自己能繼續運作。

真正的完成證據,仍要落在報表檔案、任務紀錄或其他交付位置。若重啟後收到同一項工作,應能靠同一識別碼找到結果,而不是再產生一份無法區分的新報表。

同時,要留意部署變更前後各個體連到哪版服務,以及健康失敗是否走到預期恢復路徑。這些是依產品行為推導的驗證方向,不是本刊已在正式環境做過的測試。

背景程序能連、能恢復,也能交出可追查結果,才算把這次基建更新用在工作上。對 AI 代理產生的長任務也是如此,管理運行不會自動替代內容與結果驗收。

延伸閱讀:Vercel durable-harness 是什麼?程式代理雲端當機後如何接著做

延伸閱讀:Vercel 設下靜態憑證期限:OIDC 如何運作,哪些 Marketplace 服務將被警示?

常見問題

Vercel Daemons 有健康端點,就能對外接受請求嗎?

目前不支援一般外部 HTTP、TCP 流量。內部存活檢查是不同用途,回應外部請求應採用 Services、Functions 等相應入口。

程式大多在等工作,就不會用掉 Hobby 額度嗎?

等待可減少有效 CPU 使用,但配置記憶體仍按運行時間累積。Hobby 任一月額度達上限都會停止程序,不能只看處理器是否忙碌。

自動重啟能保證任務只做一次嗎?

不能。程式可能在寫入結果前後的不同位置被中斷,需要自己保存進度、辨認重複工作,並安排完成處理後的佇列確認。

如果你想追蹤 AI 代理與背景服務如何接進實際產品,歡迎免費訂閱 AI 郵報。

資料來源