TERM을 트래핑하고 QUIT를 보낸 후 Heroku에서 Unicorn 종료 시간 초과


90

unicorn 및 sidekiq을 실행하는 Heroku 앱에 대해 R12 종료 시간 초과 오류가 발생합니다. 이러한 오류는 배포 할 때마다 하루에 1-2 번 발생합니다. 유니콘이 올바르게 응답하려면 Heroku의 종료 신호를 변환해야한다는 것을 이해하지만 아래의 유니콘 구성에서 그렇게했다고 생각했습니다.

worker_processes 3
timeout 30
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts "Unicorn master intercepting TERM and sending myself QUIT instead. My PID is #{Process.pid}"
    Process.kill 'QUIT', Process.pid
  end

  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
    Rails.logger.info('Disconnected from ActiveRecord')
  end
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts "Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is #{Process.pid}"
  end

  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
    Rails.logger.info('Connected to ActiveRecord')
  end

  Sidekiq.configure_client do |config|
    config.redis = { :size => 1 }
  end
end

오류를 둘러싼 내 로그는 다음과 같습니다.

Stopping all processes with SIGTERM
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 7
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 11
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 15
Unicorn master intercepting TERM and sending myself QUIT instead. My PID is 2
Started GET "/manage"
reaped #<Process::Status: pid 11 exit 0> worker=1
reaped #<Process::Status: pid 7 exit 0> worker=0
reaped #<Process::Status: pid 15 exit 0> worker=2
master complete
Error R12 (Exit timeout) -> At least one process failed to exit within 10 seconds of SIGTERM
Stopping remaining processes with SIGKILL
Process exited with status 137

모든 하위 프로세스가 시간 초과 전에 성공적으로 회수 된 것으로 보입니다. 마스터가 아직 살아있을 수 있습니까? 또한 로그에 표시된 것처럼 라우터가 종료 중에 dyno에 웹 요청을 계속 보내야합니까?

FWIW, 저는 Heroku의 제로 다운 타임 배포 플러그인 ( https://devcenter.heroku.com/articles/labs-preboot/ )을 사용하고 있습니다.


6
도움이된다면, 나는이 문제를 경험하고 없이 제로 다운 타임 배포 플러그인을. 누군가가 도움을 줄 수 있기를 바랍니다. 또는 당신이 그것을 이해한다면 당신은 답변을 게시 할 수 있습니다. Heroku 지원팀에 문의 하시겠습니까?
Chris Peters

Chris와 마찬가지로 다운 타임을 사용하지 않고 있으며이 문제가 발생합니다. 이것은 Heroku의 권장 유니콘 구성을 사용 함에도 불구하고 있습니다.
imderek 2013-07-12

Heroku의 권장 구성을 사용했지만 동일한 문제가 있습니다. 다운 타임없는 배포도 없습니다.
elsurudo

여기서도 동일한 문제이며 사전 부팅 플러그인을 사용하지 않습니다.
Adrian Macneil 2013-08-08

내가 알아 차린 한 가지는 일반적으로 워커 다이노에서 발생한다는 것입니다. 항상은 아니지만 일반적으로.
Chris Peters

답변:


4

사용자 정의 신호 처리가 여기에서 시간 초과를 일으키는 원인이라고 생각합니다.

편집 : 나는 Heroku의 문서에 동의하지 않는다는 이유로 반대 투표를 받고 있으며 이것을 해결하고 싶습니다.

TERM 신호를 포착하고 삼키도록 Unicorn 애플리케이션을 구성하는 것이 애플리케이션이 중단되고 올바르게 종료되지 않는 가장 가능성이 높은 원인입니다.

Heroku는 TERM 신호를 잡아서 QUIT 신호 로 변환하는 것이 하드 셧다운을 정상적인 셧다운으로 바꾸는 올바른 행동 이라고 주장하는 것 같습니다 .

그러나 이렇게하면 어떤 경우에는 종료가 전혀 발생하지 않을 위험이있는 것으로 보입니다.이 버그의 근원입니다. Unicorn을 실행하는 교수형 다이노를 경험하는 사용자는 증거를 고려하고 문서가 아닌 첫 번째 원칙에 따라 스스로 결정을 내려야합니다.


2
Heroku 문서는 여전히 " SIGTERM을 사용한 Graceful shutdown "을 다루고 있으며, Cedar 스택에서 더 이상이 작업을 수행 할 필요가 없다는 언급이 없습니다. 이것이 어디에서 찾을 수 있는지에 대한 언급이 있습니까?
Dennis

이 답변을 지원하는 문서를 찾을 수 없습니다. Unicorn과 Heroku의 문서에 따르면 Unicorn은 여전히 ​​POSIX 신호 해석의 반대를 사용합니다.
Josh Kovach

이것은 사실이 아닙니다. Unicorn은 TERM 신호를 명시 적으로 처리하지 않으면 정상적으로 종료되지 않습니다. 이를 지원하는 개발자 센터 문서는 여기에서 찾을 수 있습니다. devcenter.heroku.com/articles/rails-unicorn#config
slant

Heroku 문서에서 이러한 신호를 포착 / 변환해야한다고 말한 것을 알고 있습니다. 정상적으로 종료하려는 시도는 종료 시간 초과의 근본 원인 일 가능성이 가장 높습니다.
Winfield
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.