如何检测Resque是否启动/停止?是否有Resque.started?这类工具?
检测Resque运行状态的几种方法
嘿,刚好我之前也遇到过这个需求——Resque本身确实没有内置的Resque.started?方法,但咱们可以通过几种方式来实现类似的功能,下面给你详细说说:
方法一:检查PID文件(最直接)
当你用rake resque:start启动Resque时,它会在项目的tmp/pids目录下生成对应的PID文件(通常命名类似resque_worker_{队列名}_{进程号}.pid)。我们可以通过检查这些PID文件是否存在,并且对应的进程是否还在运行来判断状态:
def resque_running? # 匹配所有Resque worker的PID文件,路径根据你的项目配置调整 pid_pattern = Rails.root.join('tmp', 'pids', 'resque_worker_*.pid') pid_files = Dir.glob(pid_pattern) return false if pid_files.empty? # 逐个验证PID对应的进程是否存活 pid_files.all? do |file| pid = File.read(file).strip.to_i begin # 发送0号信号(不终止进程,仅检查是否存在) Process.kill(0, pid) true rescue Errno::ESRCH, Errno::EPERM # 进程不存在或无权限访问,说明已停止 false end end end
这个方法的优势是准确反映系统级的进程状态,即使Resque异常崩溃,只要进程没了就能检测到。
方法二:通过Redis查询Worker状态
Resque会把Worker的信息存在Redis里,我们可以直接查询活跃的Worker列表:
def resque_running? # 先检查是否有注册的Worker return false if Resque.workers.empty? # 进一步验证Worker是否活跃(避免异常退出后残留的无效Worker记录) Resque.workers.any? do |worker| # 这里设置5分钟阈值,可根据你的业务调整 worker.last_seen_at && (Time.now - worker.last_seen_at) < 300 end end
这个方法的好处是不需要依赖本地文件系统,适合分布式部署的场景,但要注意:如果Worker异常退出,Redis里可能会残留旧的Worker记录,所以必须结合last_seen_at时间来判断是否真的活跃。
方法三:自定义运行标记(最灵活)
你可以在启动和停止Resque时,手动在Redis里设置一个状态标记:
- 修改你的Resque启动任务,添加标记:
# 比如在resque:start任务执行后添加 task 'resque:start' do # 原启动逻辑... Resque.redis.set('resque:running', 'true') end
- 修改停止任务,清除标记:
task 'resque:stop' do # 原停止逻辑... Resque.redis.set('resque:running', 'false') end
- 然后就可以用简单的方法检测:
def resque_running? Resque.redis.get('resque:running') == 'true' end
不过这个方法的局限性是:如果Worker意外崩溃(比如服务器断电),标记不会被更新,可能导致误判。所以建议和方法一或方法二结合使用。
内容的提问来源于stack exchange,提问作者user19922
相关产品推荐
相关产品推荐

