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

如何在Rails代码中唤醒休眠的delayed_job Worker处理任务队列?

解决delayed_job休眠时立即处理新任务的方法

方法一:发送USR1信号唤醒Worker

delayed_job原生支持通过USR1信号唤醒休眠的Worker,收到信号后Worker会立即终止休眠,开始检查队列处理任务。

实现时,在任务入队后,找到delayed_job的进程ID并发送信号即可:

# 读取Worker的PID文件(默认路径是tmp/pids/delayed_job.pid)
worker_pid = File.read(Rails.root.join('tmp/pids/delayed_job.pid')).to_i
# 发送USR1信号唤醒Worker
Process.kill('USR1', worker_pid) if worker_pid > 0

如果有多个Worker进程,需要遍历所有PID分别发送信号。

方法二:动态调整sleep_delay值

delayed_job的Worker每次进入休眠前会读取Delayed::Worker.sleep_delay的值,所以可以在任务入队时临时修改这个值,让Worker下次不进入长休眠:

MyJob.perform_later(data)

# 临时将休眠延迟设为0
original_delay = Delayed::Worker.sleep_delay
Delayed::Worker.sleep_delay = 0

# 短暂延迟后恢复原设置,避免影响后续空闲状态
Thread.new do
  sleep 0.1
  Delayed::Worker.sleep_delay = original_delay
end

这种方式无需依赖进程信号,但要注意多线程环境下的并发问题。

方法三:利用Active Job的回调触发唤醒

可以在Job类中添加after_enqueue回调,自动在任务入队后执行唤醒逻辑:

class MyJob < ApplicationJob
  queue_as :default

  after_enqueue do |_job|
    worker_pid = File.read(Rails.root.join('tmp/pids/delayed_job.pid')).to_i
    Process.kill('USR1', worker_pid) if worker_pid > 0
  end

  def perform(data)
    # 你的任务处理逻辑
  end
end

推荐方案:优先使用方法一的信号唤醒机制,这是delayed_job官方设计的唤醒方式,稳定性和可靠性最高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:46:00