託管 Webhook 目標

本指南說明如何在 Knative 服務中託管 Webhook 目標。

Cloud Run functions 與 Knative Serving 的比較

Cloud Run 函式和 Knative 服務都提供良好的解決方案,可代管 Webhook 目標。一般來說,Cloud Run 函式設定快速,適合用於原型設計,也適合用於工作流程量較低的情況。Knative 服務 更具彈性,且能處理大量並行作業。

Knative serving 的適用情況如下:

  • 您使用的語言或執行階段不支援 Cloud Run functions
  • 您希望延長要求逾時時間 (最多 15 分鐘)
  • 您預期會有大量流量,且需要並行處理 (每個容器執行個體 80 項以上的並行要求)

在 Knative serving 中建立 Webhook 目標

使用 Knative Serving 時,您可以選擇任何語言來定義 Webhook 目標。您只需要建立可接受資料的 HTTP 端點即可。這項作業通常是透過 POST 執行,例如:

@app.route('/', methods=['POST'])
def index():
    data = request.get_json()

在上述範例中,網址的索引頁面已設定為僅接受 POST 要求,並預期透過 JSON 酬載傳送資料。

與 Webhook 供應商整合

提供 HTTP 回呼的大部分服務都會要求您驗證網址擁有權。 通常是傳送某種權杖、訊息或密碼,並等待有效的回應。您必須向服務供應商取得這些要求。以上述範例來說,這可能如下所示:

def index():
    data = request.get_json()
    return data['challenge']

供應商驗證擁有權後,您也必須在自己的帳戶中新增授權。

授權要求

Webhook 目標是公開網址,大多數服務都會提供符記或密鑰,確保傳入的要求來自授權服務。由於網址是公開的,您無法防止惡意嘗試將資料傳送至 Webhook 目標。不過,使用權杖或密鑰可確保您只處理來自授權來源的資料。

如要驗證要求,您可以設定密鑰,或將密鑰副本儲存為環境變數,或使用某種金鑰管理系統。

將密鑰副本儲存為環境變數時,每個要求都應在要求標頭或 JSON 酬載中包含密鑰或權杖,且您必須檢查密鑰或權杖,確保來源有效。

def index():
    request_secret = request.headers['Secret']
    if request_secret != os.environ['SECRET']:
        return ('Unauthorized', 401)

如果 Webhook 提供者不支援密鑰或其他驗證機制,只要知道 Webhook 目標網址的人,都能傳送訊息。在這種情況下,您的 Webhook 實作項目應可安全地公開至網際網路。

回覆要求

大多數服務都會規定您必須在指定時間內回覆要求。如果發生錯誤回應 (例如 HTTP 狀態碼為 4xx 或 5xx),部分 Webhook 會內建重試方法,因此您需要傳回成功狀態碼 (2xx),讓服務知道事件已正確處理。

def index():
    data = request.get_json()
    return ('', 200)

逾時

Knative serving 和 Webhook 供應商都有逾時時間。系統會採用較短的期限。如果資料處理時間超過 Knative 服務或 Webhook 提供者分配的時間,您需要使用可非同步完成處理作業的產品,例如 Pub/SubCloud Tasks。這些產品可讓您快速交接資料、立即向 Webhook 供應商傳回成功回應,並繼續處理資料,不必擔心逾時問題。這些也是處理失敗和重試的理想選項。

常見的 Webhook 模式

類型 範例
轉送資料 每當呼叫 Webhook 時,透過 Firebase 雲端通訊傳送通知。
儲存資料 將資料儲存在 BigQuery 中,以供日後分析。
觸發動作 在 GitHub 中提交新程式碼時,在 Dialogflow 上完成動作、在 Twitter 上發布回覆,或推送至預先發布環境。

後續步驟