如何根据Project模型的number_of_samples字段每日按指定次数运行Sidekiq Worker?
实现方案
1. 拆分Worker职责
把原有的批量处理Worker拆分为项目专属Worker,负责处理单个项目的所有URL,便于按项目频率灵活调度:
class ProjectPagespeedWorker include Sidekiq::Worker def perform(project_id) project = Project.find(project_id) # 替换成你实际获取项目sitemap URL的逻辑 sitemap_urls = fetch_project_sitemap_urls(project) sitemap_urls.each do |url| retrieve_data(project, url) end end private def fetch_project_sitemap_urls(project) # 示例:解析项目的sitemap.xml获取所有URL # require 'nokogiri' # require 'open-uri' # Nokogiri::XML(open(project.sitemap_url)).css('loc').map(&:text) end def retrieve_data(project, url) # 这里写你原本的retrieve_data逻辑,针对单个项目和URL puts "获取项目 #{project.id} 的URL数据:#{url}" end end
2. 引入Sidekiq Cron实现动态定时调度
使用sidekiq-cron插件,根据每个项目的number_of_samples字段配置对应频率的定时任务:
第一步:安装依赖
在Gemfile中添加:
gem 'sidekiq-cron'
执行bundle install完成安装。
第二步:创建定时任务管理类
这个类负责同步所有项目的定时任务,确保项目创建、更新、删除时,定时任务自动调整:
class PagespeedCronManager # 同步所有项目的定时任务 def self.sync_all # 先清理旧的项目相关定时任务 Sidekiq::Cron::Job.all.each do |job| job.destroy if job.name.start_with?('pagespeed_project_') end # 为每个项目创建对应频率的定时任务 Project.find_each do |project| job_name = "pagespeed_project_#{project.id}" cron_expr = case project.number_of_samples when 'once_per_day' then '0 1 * * *' # 每天凌晨1点执行 when 'three_times_per_day' then '0 1,9,17 * * *' # 每天1点、9点、17点执行 when 'hourly' then '0 * * * *' # 每小时整点执行 end Sidekiq::Cron::Job.create( name: job_name, cron: cron_expr, class: 'ProjectPagespeedWorker', args: [project.id] ) end end end
3. 绑定项目生命周期回调
在Project模型中添加回调,确保项目的频率变更或删除时,定时任务自动同步:
class Project < ApplicationRecord enum :number_of_samples, { once_per_day: 0, three_times_per_day: 1, hourly: 2 }, prefix: true after_create :sync_cron_tasks after_update :sync_cron_tasks after_destroy :sync_cron_tasks private def sync_cron_tasks PagespeedCronManager.sync_all end end
4. 初始化定时任务
首次部署或新增项目后,可在Rails控制台执行以下命令,手动同步所有定时任务:
PagespeedCronManager.sync_all
注意事项
- 确保
ProjectPagespeedWorker的逻辑是幂等的,重复执行不会导致数据异常 - 如果项目的URL数量极大,单个Worker执行时间过长,可进一步拆分为单个URL的Worker,避免超时
- 可根据业务需求调整Cron表达式的执行时间,比如把每天一次的任务改到凌晨2点等
内容的提问来源于stack exchange,提问作者SergiuXG
相关产品推荐
相关产品推荐

