使用 Upstash QStash 构建无服务器消息队列与定时任务

解决 Serverless 环境下缺乏持久化队列和定时触发器的痛点:通过 QStash 实现可靠的 HTTP 异步调用、延迟消息推送以及无服务器 Cron 任务。

为什么需要这个技能

在 Vercel Functions 或 Cloudflare Workers 等 Serverless 环境中,由于函数执行时间有限且状态不持久,很难直接实现复杂的后台任务。传统的 Redis 队列(如 BullMQ)需要维护常驻的 Worker 进程,这与 Serverless 的无状态架构相冲突。

Upstash QStash 提供了一种“HTTP 即接口”的方案。它将消息队列和定时任务转化为标准的 HTTPS 请求。你不需要部署任何 Worker,只需提供一个公开的 API 接口,QStash 就会在指定时间或事件触发时,通过 HTTP POST 将任务推送到你的接口。

适用场景

  • 定时任务:无需服务器,每天定时发送报表或清理数据库。
  • 异步解耦:将耗时操作(如发送邮件、处理图像)从主请求路径中移出,避免前端请求超时。
  • 延迟处理:设置在 1 小时后或 3 天后触发某个操作(如发送注册提醒)。
  • 可靠交付:利用内置的重试机制,确保即使目标服务临时宕机,消息最终也能送达。
  • 扇出通知:通过 URL 组一次性将同一个事件通知给多个不同的微服务。

核心工作流

1. 发布异步消息

使用 SDK 将任务发送至 QStash,并指定目标 URL。

import { Client } from '@upstash/qstash';

const qstash = new Client({ token: process.env.QSTASH_TOKEN! });

// 立即异步处理
await qstash.publishJSON({
  url: 'https://myapp.com/api/process',
  body: { userId: '123', action: 'welcome-email' },
});

// 延迟 1 小时处理
await qstash.publishJSON({
  url: 'https://myapp.com/api/reminder',
  body: { userId: '123' },
  delay: 3600, 
});

2. 配置定时 Cron 任务

在云端设定一个重复触发的调度计划。

await qstash.schedules.create({
  destination: 'https://myapp.com/api/cron/daily-report',
  cron: '0 9 * * *', // 每天 UTC 9:00 AM 触发
  body: JSON.stringify({ type: 'daily' }),
});

3. 实现安全接收端(关键步骤)

由于接口是公开的,必须通过签名验证来确保请求来自 QStash 而非攻击者。

import { Receiver } from '@upstash/qstash';

const receiver = new Receiver({
  currentSigningKey: process.env.QSTASH_CURRENT_SIGNING_KEY!,
  nextSigningKey: process.env.QSTASH_NEXT_SIGNING_KEY!,
});

export async function POST(req: Request) {
  const signature = req.headers.get('upstash-signature');
  const body = await req.text(); // 必须使用原始文本进行校验

  const isValid = await receiver.verify({
    signature: signature!,
    body,
    url: req.url,
  });

  if (!isValid) return new Response('Invalid signature', { status: 401 });

  // 校验通过后处理逻辑
  const data = JSON.parse(body);
  return new Response('OK');
}

下载和安装

下载 upstash-qstash 中文版 Skill ZIP

解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md

你可能还需要

暂无推荐