光环标志
光环基地文档
文档›Edge Functions›Jobs, cron and the DLQ

作业、cron 和死信队列

如何在请求之外运行工作:什么是作业、如何重试、cron 如何创建作业以及如何处理最终失效的作业。

9分钟 读取·级别 中间·修改于 2026年10月12日
该英文文本是根据法文原文自动生成的,尚未经过审查。
该页面已自动翻译。英文版具有权威性。
#
入队

1. 入队作业

作业是对函数的一次后台调用。使用 service_role 键将其从服务器排队。

server/enqueue.tstypescript
import { createClient } from '@aurabase/aurabase-js'

const admin = createClient(process.env.AURA_URL!, process.env.AURA_SERVICE_ROLE_KEY!)

const { data: job, error } = await admin.functions.enqueueJob('send-report', {
  payload: { month: '2026-10' },
  delaySecs: 60,   // 第一次尝试前等待 60 秒
  maxAttempts: 3,  // 默认值
})
选项默认含义
payloadnullJSON 作为请求正文提供给函数
delaySecs0第一次尝试前等待的秒数。在此之前,该作业将保持 pending 状态。
maxAttempts3尝试总数,包括第一次

您使用 getJob(id) 或 listJobs({ status, limit }) 读回作业(limit 介于 1 到 500 之间,默认为 50)。该作业有 status、 attempts、 max_attempts、 error 和日期 scheduled_at、 started_at、 completed_at。

作业是一个服务器端工具

enqueueJob、 getJob 和 listJobs 需要 service_role 密钥。公钥接收 403。

#
处理程序

2. 你的函数接收到什么

作业像任何其他请求一样调用您的函数,但您必须处理三个差异:

部分价值
方法JOB (不是 POST)
路径/jobs/<job id>
身体该作业的 payload,作为 JSON
身份标头无:x-aura-role 和 x-aura-user-id 不存在
aurabase/functions/send-report/index.tstypescript
Deno.serve(async (req) => {
  const jobId = new URL(req.url).pathname.split('/').pop()
  const { month } = await req.json()
  // …使用 jobId 作为幂等键构建并发送报告
  return new Response('ok')
})

记录了真实的呼叫 {"method":"JOB","path":"/jobs/d443d541-…","role":null,"userId":null,"body":"{\"items\":[\"a\",\"b\"],\"order\":42}"}。

作业在没有用户的情况下运行:不要依赖 x-aura-user-id。如果作品属于用户,则将用户的 ID 放入有效负载中。

#
重试

3. 生命周期和重试

statusestext
pending ──claimed──▶ running ──▶ completed
   ▲                    │
   └── after 5 s ◀── failed (attempts left)
                        └──▶ dead (no attempts left)
  • 作业至少运行一次 。如果工作线程在运行时停止,它可以运行两次,因此请使该函数具有幂等性。
  • 失败的尝试会在 5 秒的固定延迟后重试,直到达到 maxAttempts。那么工作就是 dead。延迟和默认尝试计数是服务设置(JOB_RETRY_DELAY_SECS、 JOB_MAX_RETRIES)。
  • 租约后(默认为 450 秒)仍为 running 的作业将由服务回收。
  • 已完成的作业默认保留 14 天。
函数中的 HTTP 错误并不是失败

只要您的函数 回答,无论状态代码是什么,作业都是 completed 。在实际运行中,返回 500 的函数在一次尝试后生成了 completed 作业,并且从未重试。

作业失败并仅在调用本身失败时重试:函数不存在或不活动、运行时无法访问或调用超时。如果您希望在自己的代码检测到错误时重试,请从处理程序中排队新作业(使用 delaySecs 进行退避),而不是依赖状态代码。

在同一次实际运行中,不存在的函数的作业经历了以下序列:尝试 1 在 3 秒时失败,且 Fonction 'ghost' introuvable,尝试 2 在大约 9 秒时失败,作业变成 dead ,其中 attempts 等于 max_attempts。

#
恢复

4. 死信队列

失效的作业会保留在队列中,可以列出并重试。这些路由还没有 SDK 方法:使用带有 service_role 密钥的 HTTP。

terminalbash
# 列出死掉的工作
curl "$AURA_URL/v1/functions/jobs/dlq" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# 重试一项作业
curl -X POST "$AURA_URL/v1/functions/jobs/$JOB_ID/retry" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# 重试每个失效的作业(最多 1000 个)
curl -X POST "$AURA_URL/v1/functions/jobs/dlq/requeue" -H "apikey: $AURA_SERVICE_ROLE_KEY"
# → {"data":{"requeued":1},"meta":null}

重试会将作业返回到 pending ,而不重置其尝试计数器,因此它会再进行一次尝试,如果再次失败,则返回到 dead 。在重试之前修复原因(例如,部署缺少的功能)。

#
时间表

5. 使用 cron 进行调度

cron 条目不会调用函数本身:每次触发时,它都会将作业排入队列。

server/cron.tstypescript
await admin.functions.createCronJob('nightly-cleanup', '0 3 * * *', 'cleanup', {
  payload: { dryRun: false },
})

const { data: crons } = await admin.functions.listCronJobs()
await admin.functions.deleteCronJob('nightly-cleanup') // 按名称,而不是 ID
  • 该明细表具有 5 个字段 (min hour day month weekday) 或 6 个字段 (sec min hour day month weekday)。 5 场时间表前面有 0 秒: */1 * * * * 存储为 0 */1 * * * *。
  • 诸如 @daily 之类的别名将被拒绝,并使用声明预期格式的 400 来拒绝。
  • 时间采用 UTC 时间。
  • last_run 和 next_run 是 null 直到第一次触发。在实际运行中,在 15:40 创建的计划在 15:41:00 触发,然后显示 next_run 15:42:00。
  • 当您创建条目时,有效负载将被冻结。
  • 删除未知名称会返回 404。删除 cron 条目也会阻止其触发。
  • SDK 没有 getCronJob 或 updateCronJob:删除该条目并重新创建。

对于纯粹的数据库工作,Postgres pg_cron 扩展避免了函数的往返:请参阅 Cron 页面。

最后更新· 2026年10月12日