我不得不等到整个重烤完成就上线了。上线后,我无法运行重烤,因为它会杀死服务器。我可以在默认队列上运行重烤,因为它会延迟所有其他进程,如通知。
所以我使用了这个脚本将所有重烤任务排入超低优先级的 sidekiq 队列。如果有人需要,在此分享。
# slow_rebake_resumer_ultralow.rb
# 从特定点恢复和排队重烤作业,并将它们直接发送到 :ultra_low 优先级队列。
# 在容器内执行,使用 -
# --- 配置 ---
BATCH_SIZE = 500
SLEEP_DURATION = 5
# --- 从上次更新的起点 ---
last_processed_id = 1952526
# --------------------
start_time = Time.now
total_posts = Post.count
puts "正在恢复并排队重烤作业,共 #{total_posts} 个帖子到 :ultra_low 队列..."
puts "从帖子 ID #{last_processed_id} 之后开始。"
puts "---"
loop do
# 高效地查找要处理的下一批帖子
posts_to_enqueue = Post.where("id
# 如果没有更多帖子,则退出循环
break if posts_to_enqueue.empty?
posts_to_enqueue.each do |post|
begin
# 定义所有选项在一个哈希中,包括目标队列
options = {
post_id: post.id,
cook: true,
bypass_bump: true,
queue: :ultra_low
}
# 使用正确、经过验证的语法排队作业
Jobs.enqueue(:process_post, options)
rescue =
puts "!!! 为帖子 ID #{post.id} 排队作业时出错:#{e.message}"
end
end
# 更新我们的位置到当前批次的最后一个帖子 ID
last_processed_id = posts_to_enqueue.last.id
# 获取更准确的计数以进行进度报告
enqueued_count = Post.where("id
# --- 进度报告 ---
percentage = (enqueued_count.to_f / total_posts * 100).round(2)
elapsed_minutes = ((Time.now - start_time) / 60).round(2)
puts "已排队到帖子 ID #{last_processed_id}。总共排队:约 #{enqueued_count} / #{total_posts} (#{percentage}%)"
puts "已用时间(本次会话):#{elapsed_minutes} 分钟。"
puts "作业正在发送到 :ultra_low 队列。"
# 在批次之间暂停以保持低负载
if enqueued_count
puts "休眠 #{SLEEP_DURATION} 秒..."
sleep(SLEEP_DURATION)
puts "---"
end
end
puts "\n所有剩余的重烤作业已成功排队到 :ultra_low 队列!"