You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保基于Resque的ActiveJob后台任务始终正常运行?

解决Resque Worker崩溃与持续运行的保障方案

我之前折腾过好一阵子Resque+Capistrano的部署,太懂你这种担心worker挂掉、任务没人处理的焦虑了!先给你明确答案:Resque Worker确实会崩溃——不管是未捕获的任务异常、内存泄漏撑爆进程、系统资源不足,甚至是偶尔的网络波动都可能把worker搞挂。所以必须加一层保障机制,不然后台任务很容易“失联”。

下面是我实践过的几种标准解决方案,从基础到进阶都有:

一、用进程管理工具兜底(核心方案)

Resque本身没有自带进程守护和自动重启的能力,所以必须依赖外部工具监控worker进程,挂了就自动拉起来。最常用的有这两个:

1. Systemd(Linux系统首选)

现在大部分主流Linux发行版都用systemd,它自带的进程监控功能足够稳定,不用额外装软件。

你可以创建一个systemd模板服务文件(比如/etc/systemd/system/resque-worker@.service):

[Unit]
Description=Resque Worker Instance %i
After=network.target

[Service]
User=deploy  # 换成你的部署用户
Group=deploy
WorkingDirectory=/var/www/your_app/current  # 你的应用当前目录
Environment="RAILS_ENV=production"
# 启动命令,QUEUE=*可以换成你需要的队列,COUNT=1表示每个实例一个worker
ExecStart=/bin/bash -lc 'bundle exec rake resque:work QUEUE=* COUNT=1'
Restart=always  # 不管进程怎么死的,都自动重启
RestartSec=5  # 崩溃后5秒重启
KillMode=process

[Install]
WantedBy=multi-user.target

配置好后,你可以启动多个worker实例(比如启动2个):

systemctl start resque-worker@1 resque-worker@2
systemctl enable resque-worker@1 resque-worker@2  # 设置开机自启

这样不管worker是崩溃还是被意外杀死,systemd都会自动帮你重启,完全不用手动干预。

2. Monit(轻量级监控+告警)

如果需要更精细化的监控(比如CPU/内存告警、邮件通知),Monit是个不错的选择。

先安装monit,然后在/etc/monit/conf.d/resque.conf里添加监控配置:

# 监控第一个worker进程
check process resque_worker_1 with pidfile /var/www/your_app/shared/tmp/pids/resque-1.pid
  start program = "/bin/bash -lc 'cd /var/www/your_app/current && bundle exec rake resque:work QUEUE=* COUNT=1 PIDFILE=/var/www/your_app/shared/tmp/pids/resque-1.pid'" as uid deploy and gid deploy
  stop program = "/bin/bash -lc 'cd /var/www/your_app/current && bundle exec rake resque:stop PIDFILE=/var/www/your_app/shared/tmp/pids/resque-1.pid'"
  if does not exist for 2 cycles then restart  # 进程消失就重启
  if cpu usage > 90% for 3 cycles then alert  # CPU过高告警
  if memory usage > 80% for 3 cycles then alert  # 内存过高告警

# 可以复制上面的配置,添加更多worker实例
check process resque_worker_2 with pidfile /var/www/your_app/shared/tmp/pids/resque-2.pid
  # 内容和上面类似,改pid文件名即可

配置好后重启monit,它会定时检查worker状态,挂了就重启,还能给你发邮件告警。

二、Capistrano部署时的优化

用capistrano-resque部署时,要确保部署后worker能加载新代码,同时避免旧进程残留:

  • 在你的deploy.rb里配置重启命令(对应你用的进程管理工具):
    # 如果用systemd
    set :resque_restart_cmd, 'systemctl restart resque-worker@*'
    # 如果用monit
    set :resque_restart_cmd, 'monit restart all resque_worker_*'
    
    这样部署完成后,Capistrano会自动重启所有worker,加载最新代码。
  • 不要用COUNT=N一次性启动多个worker,最好每个worker单独管理(比如systemd的@实例或monit的多个进程配置),这样单个worker崩溃不会影响其他实例。

三、额外的防护细节

  • 捕获任务异常:在ActiveJob任务里尽量捕获所有可能的异常,避免未处理的异常直接搞挂worker。比如:
    class YourJob < ApplicationJob
      queue_as :default
    
      def perform(args)
        # 你的业务逻辑代码
      rescue StandardError => e
        # 记录详细错误日志
        Rails.logger.error "Job #{self.class.name} failed with args #{args}: #{e.message}\n#{e.backtrace.join("\n")}"
        # 可选:将任务重新入队,稍后重试
        retry_job wait: 5.minutes, queue: :retry
      end
    
  • 定期重启worker:即使worker没崩溃,长期运行可能会有内存泄漏,建议每天定时重启一次(比如用cron配合systemd:0 3 * * * systemctl restart resque-worker@*),避免内存耗尽。
  • 监控队列长度:用Resque自带的resque-web面板,或者自己写个简单的脚本监控队列长度。如果某个队列的任务数持续增长,说明worker可能挂了或者处理不过来,及时告警。

内容的提问来源于stack exchange,提问作者Honza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:31:40