나는 sidekiq 작업자가 30 초를 넘겨서는 안되지만 몇 일 후에 전체 작업자 큐가 실행을 중지한다는 것을 알게 될 것입니다. 노동자들은 갇혀있다.시간 초과가 있더라도 Sidekiq 작업자가 수천 초 동안 실행 중
class MyWorker
include Sidekiq::Worker
include Sidekiq::Status::Worker
sidekiq_options queue: :my_queue, retry: 5, timeout: 4.minutes
sidekiq_retry_in do |count|
5
end
sidekiq_retries_exhausted do |msg|
store({message: "Gave up."})
end
def perform(id)
begin
Timeout::timeout(3.minutes) do
got_lock = with_semaphore("lock_#{id}") do
# DO WORK
end
end
rescue ActiveRecord::RecordNotFound => e
# Handle
rescue Timeout::Error => e
# Handle
raise e
end
end
def with_semaphore(name, &block)
Semaphore.get(name, {stale_client_timeout: 1.minute}).lock(1, &block)
end
end
그리고 우리가 사용하는 세마포어 클래스 :
여기 내 노동자입니다. (레디 스 - 세마포어 보석)
class Semaphore
def self.get(name, options = {})
Redis::Semaphore.new(name.to_sym,
:redis => Application.redis,
stale_client_timeout: options[:stale_client_timeout] || 1.hour,
)
end
end
는 기본적으로 나는 노동자가 중단 그것은 완료 상태 것이다 노동자가 결코 출마해서는 안 만초을.
누구든지이 문제를 해결하는 방법이나 원인을 알 수 있습니까? 노동자들이 EngineYard에서 뛰고 있습니다.
편집 : 추가 의견 1 개. # DO WORK는 PostgresSQL 함수를 실행할 수있는 기회를 제공합니다. 로그에서 PG :: TRDeadlockDetected에 대한 언급을 보았습니다 : ERROR : deadlock detected. 이로 인해 작업자가 제한 시간을 설정해도 완료되지 않습니까?
당신이 노동자의 "수행"방법 내부 세마포어 잠금을 사용하는 이유는 어떤 특별한 이유가 있습니까? 나는 Sidekiq + Locking의 혼합이 약간 위험하다고 생각하기 때문에 이것을 묻습니다. [Sidekiq 사람들은] (https://github.com/mperham/sidekiq/wiki/Best-Practices) 작업을 최대한 격리 시켜서 #perform 중에 잠금 작업을 수행 할 때 발생할 수있는 병목 현상이나 잠재적 교착 상태가 없음 –
sidetiq와 함께 처리 할 큐에 동일한 ID가 throw되는 경우가 있음을 알았습니다. 두 번 처리되지 않습니다. – Geesu