我一直在使用Sidekiq来处理后台工作,但我发现它对我的特定用例来说太有限了。
当用户创建帐户时,我们会从第三方服务导入他们的数据。该服务有一个速率限制,所以我可以抛出几十个工人来加速进口。
问题在于我无法控制使用Sidekiq的工作人员数量。
我可以限制每个队列的工作人员数量,但这对我没有帮助。
例如,如果10个人创建了一个帐户,我必须对所有10个人的所有数据的整体导入进行评分限制,但我真正需要的是对每个帐户进行费率限制。
实际上能够创建一个特定于用户的队列然后限制每个队列的工作者数量可能会有所帮助。
是否有类似Sidekiq的东西可以更精细地控制工人数量?
答案 0 :(得分:0)
我有类似的情况,我需要自我施加速率限制,以避免DDoSing外部服务。我使用Sidetiq来控制Sidekiq作业的排队。
使用Sidetiq,您可以定期对Sidekiq作业进行排队。在您的情况下,您可以创建一个Sidetiq作业,例如,每小时向Sidekiq添加10个用户导入作业。
class UserJobScheduler
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(0) }
sidekiq_options queue: :default
def perform
# find 10 unprocessed user ids, then queue them up
User.where(unprocessed: true).limit(10).pluck(:id).each do |user_id|
UserDataImporter.perform_async(user_id)
end
end
end
class UserDataImporter
include Sidekiq::Worker
sidekiq_options queue: :user_import, retry: false
def perform(user_id)
# import user data & mark as processed
end
end
我在实际调用我需要速率限制的API的类中将重试设置为false。这允许更精确地控制发送的请求的数量。否则,失败的请求将遵循Sidekiqs重试计划,这可能对您正在呼叫的服务过于激进
然后,您可以调整UserJobScheduler中每次运行添加的作业数量,以及将它们添加到Sidekiq队列并使用重复设置的频率,使其低于您正在调用的API的速率限制。