【问题标题】:Sidekiq freezes applicationSidekiq 冻结应用程序
【发布时间】:2013-09-26 11:31:57
【问题描述】:

所以,我有一个代码,是 rake 任务的一部分:

  class DrivingStatJob < DBJob
  sidekiq_options :queue => :driving_stats, :backtrace => true

  def perform(work_order_id)
    Rails.logger.info "Calculating driving stats for work_order #{work_order_id}"
    begin
      work_order = WorkOrder.find(work_order_id)
      return unless work_order.steps.size > 1
      DrivingStat.calculate!(work_order.steps.first.location.address, work_order.steps.last.location.address)
    rescue DrivingStatService::MissingCoordinatesError
      Rails.logger.warn "Unable to fetch coorindates for work order #{work_order_id}"
    rescue ActiveRecord::RecordInvalid => e
      Rails.logger.warn "Unable to save driving stat: #{e.message}"
    rescue ActiveRecord::RecordNotFound
      # Ignore
    rescue RuntimeError => e
      Rails.logger.warn "Unable to compute driving directions"
      Rails.logger.warn [e.message, e.backtrace].join("\n")
    end
  end
end

调用“执行”的代码:

begin
  DrivingStatJob.perform_async(id) if changed
rescue Redis::CannotConnectError => e
  logger.warn "Unable to queue up driving stats job"
  logger.warn [e.message, e.backtrace].join("\n")
end

问题:它挂在DrivingStatJob.perform_async(id) 上。它只是挂起,没有错误。 “执行”功能没有日志消息。它可能是什么? Redis 正常运行,sidekiq 正常运行。 Redis 在 127.0.0.1:6379 上运行,Sidekiq 显示它知道 Redis 在那里。

Linux Mint 15、Ruby 1.9.3、Redis 2.6、sidekiq-2.14。

【问题讨论】:

  • 您的id 是大数据结构而不是整数值吗?
  • 不,一切都很好。它只是传递一个 ID 号。
  • 同步运行作业是否按预期工作? DrivingStatJob.perform(id)
  • 是的,将其更改为 self.perform 并且工作正常。我怀疑这个问题可能是因为运行错误 - Redis 或 sidekiq。虽然我不知道是什么,但他们都保持沉默,就像没有发生任何事情一样。

标签: ruby-on-rails ruby redis rake sidekiq


【解决方案1】:

很难说发生了什么。一种找出方法是在您的 perform 方法中放置一个 debugger 并在前台运行一个 sidekiq 工作程序。这让您有机会逐步了解这些方法。

您最终将进入Sidekiq::Clients push method。这就是有趣的地方。

bundle exec sidekiq

对于 1.9,您可以使用 debugger gem

【讨论】:

  • 是的,我试过调试。似乎连这点都做不到。我不确定它是如何工作的,也许它一直在等待与 Redis 或其他东西的连接。
【解决方案2】:

您可以从您的 rake 任务中访问 sidekiq 的路线吗?从控制器中尝试它,看看它是否与 rake 任务有关。也许您缺少包含或要求。如果你摆脱了救援块,它会崩溃并给出错误吗?

我认为您遇到了 Redis 的连接错误,但它实际上是在尝试连接到 Sidekiq,而 Sidekiq 又使用了 redis。

我只是在这里吐出一些想法......

【讨论】:

    【解决方案3】:

    对 perform_async 的调用挂起。 perform_async 将作业写入 Redis,但尚未执行。我想这项工作永远不会到达 Redis,所以 sidekiq 工作人员永远不会得到执行的更改。因此,您看不到 perform 方法的日志记录。你能看到 Redis 中的作业吗?

    如果您使用的是 rails,您可以将其添加到您的 routes.rb 文件中,以便能够检查 sidekiq 队列。

    require 'sidekiq/web'
    mount Sidekiq::Web, at: '/sidekiq'
    

    如果您可以在 sidekiq 队列中看到作业,则必须启动一个工作人员来处理执行。如果没有作业,则必须检查 Redis 连接。

    【讨论】:

      【解决方案4】:

      如果你在除默认队列之外的任何队列下调度作业,你需要在启动sidekiq时显式传入队列名称。

      bundle exec sidekiq -q driving_stats
      

      此外,您可能需要确保在正确的环境中运行它

      bundle exec sidekiq -q driving_stats -e production
      

      bundle exec sidekiq -q driving_stats RAILS_ENV=production
      

      如果由于某种原因不起作用,请一起取出 sidekiq_options 并在默认队列上简单地运行它

      bundle exec sidekiq
      

      另外:您是否将 sidekiq 工作人员包括在您的父级或子级中?

      class DBJob
        include Sidekiq::Worker
      end
      

      【讨论】:

        【解决方案5】:

        问题出在 Redis 配置中。它使用了 Sentinel,为了开发而关闭 Sentinel 解决了它。

        【讨论】:

        • 有任何提示说明为什么这可以解决问题,或者是什么让您相信关闭它会起作用?
        猜你喜欢
        • 1970-01-01
        • 2019-11-04
        • 2015-05-09
        • 2014-09-29
        • 2016-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-29
        相关资源
        最近更新 更多