跳到主要内容
本页内容

将 Webhook 处理转移到队列

在 Web 应用程序中,通常需要将异步任务的处理转移到队列中,对于这些任务,客户端不需要立即响应。这样做可以使您的 Web 应用保持快速响应,而不是占用宝贵的资源等待长时间运行的进程完成。

您可能想要部署此技术的一个实例是在 处理 Webhook 时。在从不需要响应的非人工客户端接收 Webhook 请求后立即将该工作转移到队列中,以便更有效地处理。

在本教程中,我们将向您展示如何在 处理 GitHub 仓库的 Webhook 请求 时执行此技术。

在游乐场中试用 跳转到标题

✏️ 查看此游乐场,它实现了一个 GitHub 仓库 Webhook 处理程序.

使用 Deno Deploy 游乐场,您可以立即部署自己的 GitHub Webhook 处理程序,它同时使用队列和 Deno KV。我们将在稍后介绍此代码的具体内容。

为仓库配置 GitHub Webhook 跳转到标题

要试用您刚刚在游乐场中启动的 Webhook,请为您的 GitHub 仓库设置新的 Webhook 配置。您可以在仓库的“设置”下找到 Webhook 配置。

configure a github webhook

代码演练 跳转到标题

我们的 Webhook 处理程序函数非常简单 - 没有注释,它总共只有 23 行代码。它连接到 Deno KV 数据库,设置一个队列监听器来处理传入消息,并使用 Deno.serve 设置一个简单的服务器,该服务器响应传入的 Webhook 请求。

请参阅下面的注释,了解每个步骤的操作。

server.ts
// Get a handle for a Deno KV database instance. KV is built in to the Deno
// runtime, and is available with zero config both locally and on Deno Deploy
const kv = await Deno.openKv();

// Set up a listener that will handle work that is offloaded from our server.
// In this case, it's just going to add incoming webhook payloads to a KV
// database, with a timestamp.
kv.listenQueue(async (message) => {
  await kv.set(["github", Date.now()], message);
});

// This is a simple HTTP server that will handle incoming POST requests from
// GitHub webhooks.
Deno.serve(async (req: Request) => {
  if (req.method === "POST") {
    // GitHub sends webhook requests as POST requests to your server. You can
    // configure GitHub to send JSON in the POST body, which you can then parse
    // from the request object.
    const payload = await req.json();
    await kv.enqueue(payload);
    return new Response("", { status: 200 });
  } else {
    // If the server is handling a GET request, this will just list out all the
    // webhook events that have been recorded in our KV database.
    const iter = kv.list<string>({ prefix: ["github"] });
    const github = [];
    for await (const res of iter) {
      github.push({
        timestamp: res.key[1],
        payload: res.value,
      });
    }
    return new Response(JSON.stringify(github, null, 2));
  }
});