Oban背景作业模式Skill oban

Oban 是 Elixir 编程语言中用于处理后台作业的库,提供工作流、队列管理、错误处理和测试功能,适用于异步任务处理。关键词:Elixir, Oban, 背景作业, 队列管理, 错误处理, 测试, 异步任务, 后台任务

后端开发 0 次安装 0 次浏览 更新于 3/11/2026

name: oban description: Oban 背景作业模式 - 工作器、队列、错误处理、测试。在使用背景作业时加载。 user-invocable: false

Oban 背景作业参考

Elixir Oban 模式的快速参考。

Oban Pro 检测

应用模式前,检查 Oban Pro:

grep -E "oban_pro|oban_web" mix.exs
grep -r "use Oban.Pro.Worker" lib/

如果检测到 Oban Pro,查看 references/oban-pro-basics.md 了解关键区别:

Standard Oban Oban Pro
use Oban.Worker use Oban.Pro.Worker
@impl Oban.Worker @impl Oban.Pro.Worker
def perform(%Oban.Job{}) def process(%Oban.Job{})
Oban.Testing Oban.Pro.Testing

Pro 功能覆盖:工作流、批次、结构化/记录/加密工作器。 查看 references/oban-pro-basics.md 获取模式。 对于 Pro 插件(Lifeline、Smart Engine、DynamicPrioritizer), 参考 oban.pro/docs


铁律 — 切勿违反这些

  1. 作业必须具有幂等性 — 安全重试。对于支付使用幂等键
  2. 作业必须存储 ID,而非结构体 — JSON 序列化。%{user_id: 1} 而不是 %{user: %User{}}
  3. 作业必须处理所有返回值:ok, {:error, _}, {:cancel, _}, {:snooze, _}
  4. 参数使用字符串键 — 模式匹配 %{"user_id" => id} 而不是 %{user_id: id}
  5. 用户操作使用唯一约束 — 防止双击重复
  6. 切勿在参数中存储大量数据 — 存储引用(ID、路径),而非内容

快速工作器模板

defmodule MyApp.Workers.ExampleWorker do
  use Oban.Worker,
    queue: :default,
    max_attempts: 5,
    unique: [period: {5, :minutes}, keys: [:entity_id]]

  @impl Oban.Worker
  def perform(%Oban.Job{args: %{"entity_id" => id}}) do
    case process(id) do
      {:ok, _} -> :ok
      {:error, :not_found} -> {:cancel, "Entity not found"}
      {:error, :rate_limited} -> {:snooze, {5, :minutes}}
      {:error, reason} -> {:error, reason}
    end
  end
end

返回值含义

返回值 状态 行为
:ok completed 成功
{:ok, value} completed 带值的成功
{:error, reason} retryable 使用退避重试
{:cancel, reason} cancelled 永久停止
{:snooze, seconds} scheduled 延迟并重试

快速决策

选择哪个队列?

  • 关键操作 → 高并发(20+)
  • 邮件器/Webhooks(I/O) → 中并发(30-50)
  • CPU 密集型 → 低并发(3-5)
  • 外部 API → 使用 dispatch_cooldown 进行速率限制

测试模式

use Oban.Testing, repo: MyApp.Repo

# 断言已入队
assert_enqueued worker: MyApp.Worker, args: %{id: 1}

# 执行并验证
assert :ok = perform_job(MyApp.Worker, %{id: 1})

常见反模式

错误 正确
%{user_id: id} 模式匹配 %{"user_id" => id}(字符串键)
%{user: %User{}} 在参数中 %{user_id: 1}(仅 ID)
支付无幂等性 使用幂等键
忽略返回值 明确处理所有结果

参考

详细模式,请参见:

  • references/worker-patterns.md - 工作器选项、退避、超时
  • references/queue-config.md - 队列设计、池大小、cron
  • references/testing-patterns.md - 测试、断言、排空