建立工作處理常式

本頁說明如何建立「工作處理常式」,也就是處理發送工作的程式碼。您必須提供要求處理常式,才能處理該工作。從要求網址到適當處理常式的對應會在服務的 app.yaml 中宣告,方式跟任何其他要求處理常式一樣。由於是您控制如何將工作要求對應至處理常式,因此您可以直接整理工作處理常式。如果您的應用程式會處理多種不同種類的工作,您可以將所有處理常式新增至單一服務,或發布至多個服務中。

撰寫發送工作要求處理常式

Task Queue 服務會在佇列中建立 HTTP 標頭,然後將該標頭傳送至該工作目標所指定的工作站服務執行個體。工作佇列要求會從 IP 位址 0.1.0.2 送出。

當您在不同的服務中使用處理常式時,並不需要使用當初建立工作並將工作排入佇列所用的語言。

撰寫處理常式時,請遵循以下準則:

  • 程式碼必須傳回 200–299 範圍內的 HTTP 狀態碼來表示成功。如果傳回其他狀態碼,則表示工作失敗。

  • 發送工作有固定的完成期限,這取決於執行工作之服務的資源調度類型。自動調整資源配置服務必須在 10 分鐘內完成。手動和基本資源配置服務最多可執行 24 小時。如果您的處理常式超過期限,工作佇列服務會認定該工作失敗,並再次執行該工作。

  • 處理常式必須為冪等。App Engine 的 Task Queue API 設計為提供「至少一次」的遞送;也就是說,如果成功新增了工作,App Engine 就會至少將它遞送至處理常式一次。請注意,在極少數情況下,可能會發生多次執行工作的情況,所以必須確保您的程式碼在重複執行時不會有任何有害的副作用。

工作佇列會使用處理常式回應中的 HTTP 代碼,來判斷工作是否成功完成。只有 Task Queue 服務會看到處理常式的回應,而這個回應只用來判斷工作是否成功完成。佇列會忽略回應中的其他所有欄位,接著服務會捨棄回應。來源應用程式永遠接收不到任何資料。如果工作失敗,Task Queue 服務會再傳送一次要求來重試該工作。

使用者提供的資料可在要求中做為查詢字串,或做為要求主體中的酬載來遞送至處理常式。如要瞭解如何插入使用者資料,請參閱建立工作一文。如果要求包括資料,則處理常式必須知道如何將該資料插入要求。用來從要求擷取資料的確切程式碼則取決於您所使用的特定網路架構。

如要測試工作處理常式,請以系統管理員身分登入,並使用瀏覽器造訪處理常式的網址。

讀取要求標頭

發送工作的 HTTP 要求有 App Engine 所設定的特殊標頭,這些標頭含有您的處理常式可使用的工作專屬資訊。

如果外部使用者對您應用程式發出的要求中出現這些標頭,則系統會去除並更換這些標頭。但如果要求來自於已登入應用程式的系統管理員,則屬唯一例外情況,系統允許管理員設定標頭以進行測試。另一方面,當您的應用程式在開發伺服器中執行時,系統也不會移除標頭。

Task Queue 所發出的要求始終包含以下標頭:

標頭 說明
X-Appengine-QueueName 佇列名稱 (可能是「default」,代表預設的發送佇列)。
X-Appengine-TaskName 工作名稱,或系統產生的唯一識別碼 (如果沒有指定名稱)。
X-Appengine-TaskRetryCount 這個工作的已重試次數。若為第一次嘗試,此值為 0。這個數字會將工作因欠缺可用執行個體,所以從未達到執行階段而失敗的次數計算在內。
X-Appengine-TaskExecutionCount 這個工作之前在執行階段失敗的次數。這個數字不包括因欠缺可用執行個體而失敗的次數。
X-Appengine-TaskETA 指定的工作目標執行時間 (從 1970 年 1 月 1 算起,單位為秒)。

若您的要求處理常式包含任何上列標頭,則可以相信該項要求是由 Task Queue 發出的要求。

此外,Task Queue 發出的要求可能包含以下標頭:

標頭 說明
X-Appengine-TaskPreviousResponse 來自上次重試的 HTTP 回應碼。
X-Appengine-TaskRetryReason 重試工作的原因。
X-Appengine-FailFast 表示如果沒有可用的現有執行個體,則工作執行會立即失敗。

保護工作處理常式網址

如果工作會執行敏感的操作 (如修改資料),您可以保護處理常式網址,以防止惡意的外部使用者直接呼叫。您可以僅讓 App Engine 系統管理員擁有存取權,以防止使用者存取工作網址。工作要求本身由 App Engine 發出,所以可一律指定限定網址。

您可以在 app.yaml 檔案的處理常式設定中,新增 login: admin 元素,藉此限制網址。

例如:

runtime: go
api_version: go1

handlers:
- url: /worker/.*
  script: _go_app
  login: admin
- url: /.*
  script: _go_app

後續步驟