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

如何获取Sidekiq队列中指定任务的当前位置?

获取Sidekiq队列中指定任务的位置

好问题!Sidekiq官方文档里确实没有直接提供获取任务在队列中精确位置的API,但我们可以通过几种变通方法来实现这个需求,适配你用2个Worker处理默认队列的场景:

方法一:扫描队列统计位置(简单直接)

提交任务时,先记录下任务的jid(Sidekiq自动生成的唯一ID),之后定期扫描队列,统计目标任务之前的任务数量就能得到位置。

示例代码:

提交任务时保存ID:

# 提交任务并获取唯一ID
job_jid = YourWorker.perform_async(your_args)
# 可以把这个jid关联到你的业务记录(比如存到数据库或Redis),方便后续查询

查询任务位置的方法:

def get_job_position_in_queue(jid, queue_name = "default")
  target_queue = Sidekiq::Queue.new(queue_name)
  current_position = 0

  target_queue.each do |job|
    break if job.jid == jid
    current_position += 1
  end

  # 检查任务是否还在队列中
  job_exists = target_queue.any? { |job| job.jid == jid }
  job_exists ? current_position : "任务已执行完成或不存在"
end

注意:

  • 这个方法的缺点是队列越大,扫描速度越慢,如果你的队列经常有数百个任务,偶尔查询一次没问题,但频繁调用可能会影响Redis性能。
  • 如果用了Sidekiq Pro的优先级队列,任务顺序会受优先级影响,扫描时要注意优先级高的任务会排在前面,统计位置时要考虑这一点。

方法二:用Redis有序集合自定义追踪队列(高效查询)

如果需要频繁查询任务位置,可以基于Redis的ZSet(有序集合)来封装自己的队列逻辑,把任务的提交时间或优先级作为排序分数,这样就能用Redis的ZRANK命令直接获取任务位置,性能比扫描队列好很多。

示例代码:

自定义入队方法:

def enqueue_with_tracking(worker_class, args)
  job_jid = SecureRandom.uuid
  # 用时间戳作为分数,保证先进先出;如果需要优先级,可以把优先级和时间结合成分数
  sort_score = Time.now.to_f

  Sidekiq.redis do |redis|
    job_payload = {
      jid: job_jid,
      class: worker_class.to_s,
      args: args
    }.to_json
    redis.zadd("tracked_default_queue", sort_score, job_payload)
  end

  # 同时还要把任务放到Sidekiq原生队列,让Worker能处理
  worker_class.perform_async(args)
  job_jid
end

查询位置的方法:

def get_job_position_fast(jid)
  Sidekiq.redis do |redis|
    # 遍历ZSet找到目标任务的rank(注意ZRANK返回的是0开始的索引)
    rank = redis.zscan_each("tracked_default_queue").find do |payload, _|
      JSON.parse(payload)["jid"] == jid
    end&.then { |payload, _| redis.zrank("tracked_default_queue", payload) }

    rank ? rank + 1 : "任务已执行完成或不存在"
  end
end

注意:

  • 这个方法需要同步维护自定义ZSet和Sidekiq原生队列,任务执行完成后要记得从ZSet中移除,避免数据冗余。
  • 如果你需要Sidekiq的重试、死信队列等功能,还要额外处理这些场景下的ZSet更新逻辑。

方法三:估算等待时间(无需精确位置)

如果不需要精确位置,只是想知道任务大概还要等多久,可以通过统计历史数据来估算:

  • 记录每个Worker处理任务的平均耗时
  • 用当前队列长度乘以平均耗时,再结合任务提交的时间,就能算出大致的等待时间

这种方法不需要扫描队列,性能最好,适合只需要大致预期的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:08:02