大家好,分享一個在執行客戶 n8n 工作流程時學到的實際經驗,這是一種在筆電上運作完美,卻在正式環境中出錯的錯誤。
那封沒人想要的凌晨一點電子郵件
本文分享了在使用 n8n 建立客戶工作流程時遇到的時區問題,導致原定上午九點的排程在凌晨一點執行,並產生過時資料。作者解釋了伺服器時區與工作流程日期計算之間的差異,並提出了兩階段的解決方案。解決方案包括明確設定 GENERIC_TIMEZONE 環境變數,以及在工作流程中加入驗證節點來記錄實際執行時間。

大家好,分享一個在執行客戶 n8n 工作流程時學到的實際經驗,這是一種在筆電上運作完美,卻在正式環境中出錯的錯誤。
那封沒人想要的凌晨一點電子郵件
我部署了一個每日摘要工作流程:每天早上九點,抓取前一天的指標,讓大型語言模型(LLM)寫一份簡短摘要,然後透過電子郵件發送給客戶。這個流程完美運作了數週。
接著客戶聯繫我:「為什麼我們在凌晨一點收到昨天的摘要?」我什麼都沒改。排程觸發器顯示九點,執行列表也顯示九點。然而,電子郵件卻在他們當地時間凌晨一點送達。
一份「早安」摘要,在凌晨一點送達,這可不是我最光榮的時刻。
你沒注意到的兩個時鐘
每個排程工作流程至少有兩個時區在運作,而我們大多數人只會想到其中一個。
1. 伺服器時區:n8n 會根據其執行機器(或容器)的時區來評估排程觸發器的 cron 表達式。在你的筆電上,這就是你的本地時區,九點意味著你當地時間的九點,一切運作正常。
但在正式環境中,你的 n8n 很可能是一個 Docker 容器,其時區設定為 TZ=UTC。相同的 cron 表達式,相同的觸發器,現在九點就意味著 UTC 時間的九點,這對我的客戶(UTC+8)來說就是凌晨一點。
2. 工作流程本身的日期計算:在工作流程內部,$now 和「日期與時間」節點也使用伺服器時鐘。我的摘要在執行時計算「昨天的指標」。
在當地時間凌晨一點執行時,根據伺服器時鐘,「昨天」仍然是正確的,但上游的指標彙總尚未完成,因此摘要是基於過時的資料建立的。
一個時區的偏差,導致了錯誤的時間和錯誤的資料。這就是為什麼它只會在正式環境中發生:開發環境(筆電,本地時區)和正式環境(容器,UTC)悄悄地不一致,而 n8n 中沒有任何警告。
解決方案:固定時區,然後驗證
這分為兩個部分:設定和驗證習慣。
第一部分:固定 GENERIC_TIMEZONE。n8n 有一個環境變數,可以控制排程觸發器和「日期與時間」節點的時區。如果未設定,它會回退到伺服器時區。
我現在在每次部署時都明確設定它:GENERIC_TIMEZONE=Asia/Shanghai。只需一行程式碼。排程觸發器會根據這個時區評估 cron 表達式,無論容器認為自己是什麼時區。(如果有多個受眾?一個工作流程只有一個評估時區,請固定到該受眾的時區,並為其他受眾使用單獨的觸發器。)
第二部分:透過第一次實際執行來驗證。我不再單獨信任設定了。我部署的每個排程工作流程都以一個防護節點開始,該節點會記錄實際執行時間和時區:{{ $now.toFormat('yyyy-MM-dd HH:mm z') }}。
第一次實際執行會將其實際的本地時間寫入執行日誌。如果它沒有顯示我預期的時間,我會在第一天就發現它,而不是透過客戶在凌晨一點通知我。這只需三十秒鐘來添加,卻已經幫我省了兩次麻煩。
日光節約時間(DST)加碼
如果你的固定時區有日光節約時間,cron 在轉換日可能會重複觸發或跳過(凌晨 2:30 可能會發生兩次,或從未發生)。
對於每天只執行一次的工作,我會避開日光節約時區的凌晨 1:00 到 3:00 之間。這聽起來很無聊,但你絕不會希望收到「在春季調快時間的週日執行了兩次」這樣的錯誤報告。
我現在為每個排程工作流程執行的檢查清單
部署中明確設定 GENERIC_TIMEZONE(絕不繼承自容器)。
cron 時間以受眾的時區表示,而不是我的時區。
第一個節點記錄實際執行時間和時區;我會檢查第一次實際執行。
任何「昨天/今天/本週」的日期計算都使用固定的時區。
在有日光節約時間的時區中,避免在凌晨 1:00 到 3:00 之間設定每日觸發器。
時區問題在客戶於凌晨一點讀到你的早晨摘要之前,看起來都「顯然沒問題」。固定它、記錄它、檢查第一次執行。更多這些生產模式(包含可匯入的 JSON):github.com/zhp910318/n8n-ai-automation-lab,採用 MIT 授權。
覺得值得一看?分享給朋友。
以上為 AI 自動翻譯導讀。原文版權歸 n8n Community 所有, 建議透過「閱讀原文」前往原始網站,以取得最完整資訊並支持原作者。
43 個來源、每 2 小時更新,太多看不完。電子報每週挑最值得看的幾則,附上 Max 的看法。