gpt4 book ai didi

ruby - 将重试的 sidekiq 作业放在队列的开头

转载 作者:行者123 更新时间:2023-12-04 15:19:48 25 4
gpt4 key购买 nike

我有大约 100000 个作业的 sidekiq 队列。有些工作失败了,这没关系,因为它们通常在 sidekiq 重试时成功。

然而,来自 RetrySet 的那些作业被添加到我们队列的末尾。很长一段时间过去了,直到再次处理作业。

如何将重试的作业放在队列的开头,使其优先处理?

最佳答案

我不相信对此有一个很好的答案,因为如果我没记错的话,Sidekiq 队列使用 Redis 列表,所以有一个 FIFO 的期望。重试的作业排在同一个队列中,这意味着它们将始终排在最后。

一种方法不是很好,也不是我推荐的方法,它是添加另一个队列并改为将作业重试发送给它:

# config/sidekiq.yml
---
:queues:
- default
- my_worker_retries

设置worker不重试:

class MyWorker
include Sidekiq::Worker
sidekiq_options retry: false
end

确保您的工作人员可预见地引发错误,如下所示:

class MyWorker
include Sidekiq::Worker
sidekiq_options retry: false

def perform(arg)
raise ArgumentError
end
end

添加一些逻辑来处理该异常,然后通过新创建的队列再次运行此作业:

class MyWorker
include Sidekiq::Worker
sidekiq_options retry: false

def perform(arg)
begin
raise ArgumentError
rescue ArgumentError => error
MyWorker.set(queue: :my_worker_retries).perform_async(arg)
end
end
end

这意味着任何失败并在 my_worker_retries 队列中排队的作业都可能陷入无限循环——作业失败、获救、排队、再次失败——更糟糕的是,由于您没有使用 Sidekiq 的内置重试排队机制,因此没有后退算法来确保重试不会像 CPU 可以处理的那样快。

整个东西都很脆弱。

您可以尝试通过传递一个参数来防止这种情况发生,该参数指示该作业已重试了多少次,以便您可以在某个次数后停止:

class MyWorker
include Sidekiq::Worker
sidekiq_options retry: false

MAX_RETRIES = 5

def perform(arg, retries = 0)
raise 'Too many retries' if retries >= MAX_RETRIES

begin
raise ArgumentError
rescue ArgumentError => error
MyWorker.set(queue: :my_worker_retries).perform_async(arg, retries + 1)
end
end
end

您可以扩展它以拥有您自己的退避算法:

MyWorker.set(queue: :my_worker_retries).perform_in((retries + 1).hours, arg, retries + 1)

这些都不是理想的,但它确实回答了问题。我当然希望有比这更好的解决方案。

有一些 Sidekiq 扩展可能有用,例如 https://github.com/chartmogul/sidekiq-priority_queue ,但我以前没有使用过它们。

关于ruby - 将重试的 sidekiq 作业放在队列的开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63569007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com