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

如何根据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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:30:57