3

resque我们有一个用于后台处理的多租户应用程序。

我们偶尔会遇到的问题是单个租户在很短的时间内执行大量后台工作。这基本上会阻塞队列一段时间——当我们处理这个单一租户的积压工作时,所有其他租户的工作都会被延迟。

是的,我们可以增加更多的工人。但这并不是真正的“解决方案”,它更像是一种创可贴,仍然会导致其他租户延迟——只是随着我们处理速度更快而延迟更短。

是否有更多多租户友好的使用方式resque?还是完全对多租户友好的后台队列?

我们正在研究:

  • 每个租户使用一个队列,每个租户使用一个工作人员(动态创建的队列?)
  • 修改resque,以便它以某种方式循环每个租户的队列

我们只是想知道我们是否缺少某些东西/更好的方法......

4

1 回答 1

0

您可以使用您Rails.cache为每个参与者维护临时作业计数器,并根据活动作业的数量将作业分配到不同的队列。

您需要对作业进行子类化以支持不同的队列,并编写一个方法来解析为作业的正确类。就像是:

class Worker

   cattr_acessor :tenant_id

   class Worker::Low < Worker
     @queue = :low
   end

   class Worker::High < Worker
     @queue = :high
   end

   def self.queued
      "#{name}::#{resolved_queue(tenant_id)}".constantize
   end

   def self.resolved_queue tenant_id
     count = job_count(tenant_id)
     if count > 1000
       'Low'
     else
       'High'
     end
   end

   def self.cache_key tenant_id
     "job_count/#{tenant_id}"
   end

   def self.job_count tenant_id
     Rails.cache.fetch(cache_key(tenant_id)){0}
   end

   def self.job_count_increment tenant_id
     Rails.cache.fetch(cache_key(tenant_id)){0}
     Rails.increment(cache_key(tenant_id)){0}
   end

   def self.job_count_decrement tenant_id
     count = Rails.cache.fetch(cache_key(tenant_id)){0}
     Rails.decrement(cache_key(tenant_id)){0} if count > 0
   end
end

然后Worker.queued(tenant_id).perform在您运行工作程序时调用,并确保在应用程序Worker.tenant_id中设置为 on before_filters。有关队列和优先级的更多信息,请参阅Resque Priorities 和 Queue Lists

您应该在作业队列上调用增量并从作业中调用减量。

丑陋,但可行。

并且可以通过一些元编程变得更加枯燥 - 将这些方法提取到一个模块中,然后确保在模块包含上生成队列子类。

于 2015-11-24T19:18:52.030 回答