Sidekiq 完全指南:Ruby 后台任务处理的生产级实践

Sidekiq 是 Ruby 生态最流行的后台任务框架,基于 Redis 与多线程实现高并发任务处理。本文讲解 Worker 创建、队列优先级、定时任务、Web 监控界面与生产监控方案。

最佳实践
任务队列与工作节点调度插画

Sidekiq 把耗时操作(发邮件、调外部 API、生成报表)从 Web 请求中剥离,任务推入 Redis 队列后由多线程 Worker 并发消费。核心要点:任务必须幂等、参数只传可序列化基本类型、按业务划分队列配优先级,生产环境必须监控队列深度与失败率。

为什么是 Sidekiq

与基于数据库或进程模型的方案相比,Sidekiq 用线程并发 + Redis 存储实现了一个甜蜜点:单进程轻松并发几十个任务、内存占用仅为多进程方案的几分之一、Redis 持久化保证重启不丢任务。GitHub、Shopify 等公司每天用它处理上亿级任务,成熟度毋庸置疑。

搭建与第一个 Worker

gem install sidekiq
# 需要本地或远程 Redis 服务
class ImageProcessJob
  include Sidekiq::Job
  sidekiq_options queue: :images, retry: 5

  def perform(image_id, operation)
    image = Image.find(image_id)
    ImageProcessor.call(image, operation)
  end
end

# 入队
ImageProcessJob.perform_async(image.id, 'resize')
ImageProcessJob.perform_in(10.minutes, image.id, 'thumbnail')   # 延迟任务
ImageProcessJob.perform_at(1.day.from_now, image.id, 'archive') # 定时任务

参数红线:只传基本类型(字符串、数字、数组、简单哈希),传 ActiveRecord 对象会被序列化成一团乱麻——传 id,执行时现查。

启动消费进程:

bundle exec sidekiq -q images -q default

队列与优先级

Sidekiq 的队列是加权轮询:-q critical,4 -q default,1 表示 critical 队列被检查的频率是 default 的 4 倍。队列划分按"延迟敏感度"而非技术类型:支付回调、用户等待中的操作进 critical;报表、清理任务进 low。Rails 项目里 Sidekiq 实现 ActiveJob 接口,queue_as 声明队列,与原生 Worker 可以混用。

失败与重试机制

任务抛异常时 Sidekiq 自动重试,默认 25 次、指数退避(跨度约 21 天)。可配置项:

sidekiq_options retry: 3                       # 只重试 3 次
sidekiq_options retry: false                   # 不重试
sidekiq_options dead: false                    # 重试耗尽后不进 Dead 队列

sidekiq_retries_exhausted do |msg, exception|
  ErrorReporter.notify(exception, job: msg['class'])
end

重试机制的前提是幂等性:任务执行两次和执行一次结果一致(用唯一键 upsert、先查状态再操作)。任何"执行一次扣一次款"式的设计在重试面前都是资损事故。

Web 监控界面

挂载自带 Web UI:

# config/routes.rb
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'

实时查看各队列深度、忙碌线程、重试与死信任务,支持手动重试/删除。生产环境务必加认证(如约束在管理员或内网)。

监控 Sidekiq 重试与 Worker 容量

Sidekiq 的重试会掩盖短暂失败,也可能造成持续积压。把任务类别、重试次数、入队与执行时间写入结构化日志,在观测云中检查失败集中在哪类任务、哪个版本。Redis 指标用于排查存储压力;队列长度和延迟应从 Sidekiq 数据或自定义指标补充。Worker 调用链需先验证 SDK 对 Sidekiq 版本的支持,不能仅凭安装 DataKit 就认为所有任务已被追踪。

接入文档:Redis 采集 · 日志采集 · Ruby APM 接入 · 监控器与告警策略。

常见问题(FAQ)

Q:Sidekiq 和 GoodJob 怎么选?

已有 Redis 或需要超高吞吐选 Sidekiq;想精简基础设施、任务量中等选 GoodJob(PostgreSQL 驱动,事务安全更好)。详细对比见本系列《GoodJob 和 Sidekiq 选哪个》。

Q:进程被 kill 时正在执行的任务会丢吗?

免费版可能丢失(任务从队列弹出即删除);Sidekiq Pro 的 super_fetch 提供崩溃恢复。架构层面通用的解法是任务幂等 + 业务层对账(如定时扫描"卡中间态"的订单补跑任务)。

Q:如何限制某个任务的执行频率(防第三方 API 限流)?

基础版用单独低并发队列(-q api,1 单线程串行);精细限流用 sidekiq-limit_fetch、sidekiq-throttled 等社区 gem,支持按窗口配额控制。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台