描述問題/錯誤/問題
我的 Google Sheets Trigger 節點(每分鐘輪詢一次,rowAdded 事件)在監控兩個不同 Google Sheets 的兩個獨立工作流程中間歇性出現 503 錯誤,使用兩個不同的 OAuth2 認證。此問題從 7 月 12 日 06:56 至 7 月 13 日 23:03 反覆發生。
發文前,我已經檢查過標準原因:
兩個 Google Sheets OAuth2 認證都顯示「帳戶已連接」,無需重新驗證。
n8n 自己的狀態頁面顯示一個事件(7 月 13 日本地時間 10:58 至 11:18,持續 20 分鐘),但不與我的任何錯誤時間戳重疊。
Google Workspace 的狀態儀表板在整個期間顯示 Sheets 狀態良好。
在這些錯誤開始之前,其中一個受影響的工作流程上已啟用「失敗時重試」,但錯誤仍然存在,因此這似乎不是重試可以解決的正常瞬間故障。
我找到了兩個類似的過去討論串(下面有連結),其中建議的修復方法是啟用「失敗時重試」,但由於我的一個工作流程上已啟用此功能且沒有幫助,我想將此標記為可能是不同或更持久的問題。
相關討論串我找到:
Hello , I am using selfhosted n8n ( version 0.177.0 ) .
I have setup cron node to run my workflow every 5 minutes. however, from time to time, I receive the error below.
[image]
[image]
[image]
However, when i did not do any changes and re run the workflow manually, it is working well.
[image]
Google Sheets Trigger executions - Could not complete
錯誤訊息是什麼(如果有的話)?
{
“errorMessage”: “服務不可用 - 稍後重試或考慮將此節點設定為自動重試(在節點設定中)”,
“errorDescription”: “該服務目前不可用。”,
“errorDetails”: {},
“n8nDetails”: {
“n8nVersion”: “2.29.8 (Cloud)”,
“binaryDataMode”: “filesystem”
}
}
請分享您的工作流程
(在您的畫布上選擇節點並使用鍵盤快捷鍵 CMD+C/CTRL+C 和
CMD+V/CTRL+V 複製和貼上工作流程。)
分享最後一個節點返回的輸出
不適用。Trigger 節點本身在返回任何輸出之前失敗,因此下游節點不執行。
關於您的 n8n 設定的資訊
n8n 版本:2.29.8
資料庫(預設值:SQLite):n8n Cloud 管理
n8n EXECUTIONS_PROCESS 設定(預設值:own、main):預設值(Cloud 管理)
透過以下方式執行 n8n(Docker、npm、n8n cloud、桌面應用程式):n8n Cloud
作業系統:n8n Cloud
@Kalon
每分鐘輪詢會耗費大量資源,也容易出現這些錯誤。處理「列已新增」事件最強大的方法是讓 Google Sheets 推送 資料到 n8n,使用簡單的 Google Apps Script 即可實現即時推送。
將 n8n 中的 Google Sheets 觸發器 替換為 Webhook 節點 。
複製生產環境 Webhook 網址。
在你的 Google 試算表中,前往擴充功能 →→ Apps Script ,貼上類似以下的指令碼:
function onFormSubmit(e) {
var url = "YOUR_N8N_WEBHOOK_URL";
var options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(e.values)
};
UrlFetchApp.fetch(url, options);
}
在 Apps Script 儀表板(時鐘圖示)設定可安裝的觸發器 ,讓 onFormSubmit 函式在「表單提交時」或「變更時」執行。
歡迎 @Kalon !
這裡的 503 來自 Google 的 API,而不是 n8n — Sheets 輪詢觸發器在每個間隔調用 Sheets API,Google 有時會在服務邊緣丟棄請求,即使公開狀態頁面顯示正常。有兩件事要檢查:首先,在執行日誌中查看原始錯誤主體 — 如果 JSON 中包含 backendError 或 serviceUnavailable,那就證實了 Google 後端是罪魁禍首。其次,嘗試將輪詢間隔從每 1 分鐘改為每 5 分鐘 — 使用多個認證條件對同一 Sheets API 配額進行激進輪詢可能會加劇此問題。如果你需要近乎實時的檢測,改用基於 webhook 的方法(透過 Google Apps Script 在工作表變更時觸發你的 n8n webhook)比輪詢更可靠,並且完全避免了這類錯誤。
嗨 @Kalon
如果兩個認證都是「使用 Google 登入」受管 OAuth2 類型,它們會通過 n8n 在 Cloud 上的共享 Google 用戶端運行,這就是為什麼兩個不同的帳戶在同一個視窗中失敗,以及為什麼你沒有 API 儀表板可以查看的原因。使用來自你自己 Google Cloud 專案的用戶端,將認證重新建立為自訂 OAuth2,並將兩個工作流程指向它。然後在該專案中打開 API 和服務 > Google Sheets API > 指標:回應代碼分析會顯示 Google 附加到每個 503 的原因,你的輪詢會針對你自己的用戶端而不是共享用戶端運行。
503 是來自 Google 那邊,不是 n8n — 在 n8n Cloud 上,Sheets Trigger 使用 n8n 的共享 Google OAuth 客户端,所以你與其他每個 Cloud 用戶共享該客户端的 API 配額。當 Google 限流該共享專案時,即使你自己的憑證和流量都沒問題,你仍然會間歇性地收到 503。這就是為什麼它會同時影響兩個使用不同憑證的工作流程,以及為什麼「失敗時重試」無法清除它 — 輪詢 trigger 不會重新掃描在失敗週期中跳過的列,所以真正的風險是無聲地遺漏列,而不是錯誤行本身。
兩個修復方案,按影響程度排序:
改用自訂 OAuth2 — 建立你自己的 Google Cloud 專案 + OAuth 客户端,並將其用作憑證。這樣你就能從共享配額改為使用自己的配額,通常會直接消除間歇性 503。
用推送替換輪詢 — 使用 Google Apps Script onChange trigger,將新列 POST 到 n8n Webhook。無輪詢意味著沒有遺漏列的窗口(在 Apps Script 端用 try/catch 包裝,因為它有自己的配額)。
無論哪種方式,都要加上一個小的安全網:每 15–30 分鐘執行一次的排程工作流程,重新讀取過去一小時的列,並根據列 id 或時間戳欄位去重 — 這樣在 503 窗口期間遺漏的任何內容仍然會被拾取。
上面關於共享 OAuth 客戶端的解釋很可能是對的,改用自訂客戶端是正確的下一步。但這裡的每個人(包括我,直到我重新閱讀你的文章後)都在爭論應該修復哪個 輪詢,我認為更有用的問題是你為什麼要輪詢。
60 秒間隔的 rowAdded 是 n8n 每天向 Google 詢問「有什麼改變嗎?」1,440 次(每個工作流程),永遠如此 — 而絕大多數這些呼叫都返回無結果。每一個都是遭遇 503 的機會,改用你自己的 OAuth 客戶端會縮小這種暴露而不會消除它,因為 503 是 Google 後端在負載下返回的,無論你用誰的客戶端都是一樣。
推送而不是輪詢。 在試算表中:擴充功能 → Apps Script,然後像這樣:
function onRowAdded(e) {
UrlFetchApp.fetch('https://<your-n8n>/webhook/<path>', {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ range: e.range.getA1Notation(), values: e.range.getValues() })
});
}
```
...綁定為可安裝的觸發器(觸發器 → 新增觸發器 → 變更時,或如果列來自表單則提交表單時)。在 n8n 中,將試算表觸發器換成 Webhook 節點。
這會為你帶來什麼:**零個試算表 API 呼叫**,所以你追蹤的整個失敗類別會消失而不是變得更少。Apps Script 在試算表*內部*執行,不會接觸試算表 REST API 或其配額,所以 Google API 503 無法丟失你的事件。這也是即時的而不是最多延遲 60 秒,而且它不花錢。
兩個誠實的警告,因為這並非免費的:
- `onChange` 不會為*其他* API 寫入或指令碼進行的編輯而觸發。如果某些列是通過試算表 API 而不是人類或表單送達的,這些不會觸發它 — 在承諾之前檢查列實際上是如何送達的。
- 你現在依賴你的 webhook 可以到達。Apps Script 不會有意義地重試,所以 POST 期間 n8n 重新啟動會丟失該事件。
這就是為什麼上面建議的安全網掃描無論你使用哪個觸發器都保留:一個排定的工作流程,重新讀取最後 N 列並使用列 id 進行去重。推送為了延遲,掃描為了正確性。這個組合是我在生產環境中運行的,這就是使「我是否在 503 窗口期間無聲地錯過一列?」這個問題成為你能夠實際回答而不是假設的東西。
在你繼續之前,還有一件值得檢查的事情:在那些失敗窗口期間,任何列實際上被*遺漏*了,還是下一個成功的輪詢撿起了它們?503 很吵鬧和煩人,但無聲的資料遺失才是真正會傷害你的,值得確認你遇到的是哪一個。
@Kalon
n8n 中的 503 Service Unavailable (服務暫時無法使用)錯誤(Google Sheets Trigger)表示目的地伺服器端出現暫時性問題——在此案例中,Google Sheets API 暫時無法處理該請求。
原因和解決方案可分解如下:
是什麼導致了這個問題?
Google 伺服器過載或暫時停機(瞬時錯誤): 這是最常見的原因。Google 的伺服器可能正在重新啟動、進行維護,或在該特定時刻處理異常高的流量。
輪詢頻率過高: 工作流程每 1 分鐘檢查一次更新。以此高頻率執行輪詢觸發器可能會導致 Google API 將請求視為過於頻繁,暫時中斷連接以防止伺服器過載(即使它沒有明確返回 429 Too Many Requests 錯誤)。
間歇性網路問題: 你的 n8n 實例與 Google 伺服器之間可能出現短暫的連接中斷或握手逾時。
如何修復?
1. 啟用「失敗時重試」(如系統建議) 這是處理此類瞬時錯誤的最有效方法。
2. 增加輪詢間隔 如果你的觸發器檢查資料太頻繁(例如每分鐘),請考慮延長間隔以減少整體 API 負載。
將間隔更改為每 5 分鐘 或 15 分鐘 檢查一次,如果你的使用案例不需要嚴格的即時更新。
3. 檢查 Google Cloud 控制台配額 如果你使用的是自己的自訂 OAuth2 認證(而不是 n8n 的預設雲端認證):
登入 Google Cloud 控制台並檢查 Google Sheets API 的「配額」部分,確保你沒有達到每分鐘或每天的限制。
4. 檢查 Google 的服務狀態 有時 Google Workspace 本身會遇到中斷。你可以在 Google Workspace 狀態儀表板 上監控其服務的實時健康狀況。如果 Google 出現大規模停機,你只需等待他們的團隊解決此問題。
我認為這裡有幾件事混在一起了。
503 通常是 Google 端的暫時性故障,但我不會自動把它和配額問題或過度輪詢歸為一類。如果 Google 認為你超過了配額,通常會看到 429 或配額相關的 403 回應,而不是 503。
另外,如果故障發生在觸發程序輪詢層級本身,我不太確定啟用失敗時重試 一定是答案。觸發程序節點的行為與一般工作流程節點不同,所以確認重試是否實際適用於 Google Sheets 觸發程序輪詢故障或只適用於下游節點執行會很有用。
共享 OAuth 的解釋似乎更加可信,特別是因為看起來多個用戶在同一時間出現這個問題。改用自訂 OAuth 用戶端可以讓你不受共享用戶端行為的影響,這可能是我首先會測試的東西。
不過,我認為更重要的問題是 Adam 之前提出的那個:
真的有資料遺失嗎?
是列永久被遺漏了,還是下一次成功的輪詢只是趕上並正常處理了它們?
因為這兩者有很大的區別:
日誌中有雜亂的暫時性 503 錯誤,以及
無聲的資料遺失。
前者很煩人。
後者是一個生產問題。
關於 Apps Script 建議,有一個重要的細節值得一提:
e.range 和 e.values 適用於某些觸發程序類型,例如表單提交時 ,但它們不一定存在於一般的變更時 可安裝觸發程序。所以示例實現可能對某些工作流程完美運行,而對其他工作流程立即失敗,取決於行如何進入工作表。
Webhook 方法仍然很吸引人,因為消除輪詢就消除了整個輪詢故障類別,但它反而引入了不同的故障模式:
如果 webhook 端點在傳遞過程中不可用,Apps Script 不會為你提供持久重試或隊列。
就我個人而言,我會執行:
用於低延遲的推送/webhook 傳遞,
使用列 ID 的冪等處理,
以及定期重新檢查最近列的排程協調工作流程。
推送以求速度。
掃描以求正確性。
該組合可以應付 API 故障、webhook 停機、工作流程重新啟動以及最終出現在生產中的幾乎所有醜陋邊界情況。
在這一點上,我在得出結論之前對三件事感興趣:
共享 n8n OAuth 還是自訂 OAuth?
是否真的有列被遺漏了?
所有受影響的用戶是否在同一個 n8n Cloud 地區或基礎設施中執行?
這些答案可能會告訴我們我們看的是預期的 Google 暫時性故障,還是值得進一步調查的實際 n8n 端事件。
嗨 Kalon,
503 Service Unavailable 錯誤通常表示 Google Sheets API 伺服器暫時過載或因為並發請求過高而強制實施速率限制。
由於你在多個獨立工作流程和 OAuth 認證憑證中每 1 分鐘輪詢一次,你極有可能觸發了 Google 的並發請求配額,導致他們間歇性地拒絕請求。由於「失敗時重試」搭配預設的短延遲無法捕捉此情況,區塊持續時間超過了重試嘗試。
以下是兩個永久解決此問題的方法:
動態輪詢與指數退避(快速修復):
• 前往 Google Sheets 節點設定 → 在「失敗時重試」下方,將最大嘗試次數增加到 5。
• 將重試延遲(等待時間)增加到至少 5000ms 或 10000ms。這樣可以給 Google API 足夠的冷卻時間在重試之間吸收暫時的 503 阻塞。
從輪詢轉向透過 Webhooks 的推送架構(推薦 ):
與其讓 n8n 每分鐘輪詢 Google Sheets,你可以反轉架構。
• 將 Google Sheets 觸發器替換為 n8n Webhook 節點。
• 將簡單的 5 行 Google Apps Script(onEdit 觸發器)新增到你的 Google Sheets,每當新增一列時自動向你的 n8n Webhook 發送 POST 請求。
這完全繞過了輪詢速率限制,完全消除了 503 錯誤,並節省了大量的 n8n 執行開銷。
如果你需要幫助建構 Google Apps Script 設定,請告訴我,我可以與你分享指令碼區塊!