Unicorn waktu keluar waktu tunggu di Heroku setelah menjebak TERM dan mengirim BERHENTI

90

Saya menerima kesalahan R12 Exit Timeout untuk aplikasi Heroku yang menjalankan unicorn dan sidekiq. Kesalahan ini terjadi 1-2 kali sehari dan setiap kali saya menerapkan. Saya mengerti bahwa saya perlu mengubah sinyal shutdown dari Heroku agar unicorn merespons dengan benar, tetapi saya pikir saya telah melakukannya di konfigurasi unicorn di bawah ini:

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

Log saya yang mengelilingi kesalahan terlihat seperti ini:

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

Tampaknya semua proses anak berhasil diambil sebelum batas waktu. Mungkinkah tuan masih hidup? Juga, haruskah router masih mengirimkan permintaan web ke dyno selama dimatikan, seperti yang ditunjukkan di log?

FWIW, saya menggunakan plugin penyebaran zero downtime Heroku ( https://devcenter.heroku.com/articles/labs-preboot/ ).

middkidd
sumber
6
Jika membantu, saya juga mengalami masalah ini tanpa plugin penerapan zero downtime. Saya harap seseorang dapat membantu atau Anda dapat memposting jawaban jika Anda mengetahuinya. Mungkin menghubungi dukungan Heroku?
Chris Peters
Sama seperti Chris, saya tidak menggunakan zero downtime, dan saya mengalami masalah ini. Ini meskipun menggunakan konfigurasi unicorn yang direkomendasikan Heroku.
imderek
Saya mengalami masalah yang sama, meskipun menggunakan konfigurasi yang direkomendasikan Heroku. Tidak ada penerapan zero-downtime juga.
elsurudo
Masalah yang sama di sini, dan tidak menggunakan plugin preboot.
Adrian Macneil
Satu hal yang saya perhatikan adalah bahwa ini BIASANYA terjadi pada dinos pekerja. Tidak selalu, tapi biasanya.
Chris Peters

Jawaban:

4

Saya pikir penanganan sinyal khusus Anda adalah penyebab waktu tunggu di sini.

EDIT: Saya mendapatkan downvoted karena tidak setuju dengan dokumentasi Heroku dan saya ingin membahas ini.

Mengonfigurasi aplikasi Unicorn Anda untuk menangkap dan menelan sinyal TERM adalah kemungkinan besar penyebab aplikasi Anda macet dan tidak dimatikan dengan benar.

Heroku tampaknya berpendapat bahwa menangkap dan mengubah sinyal TERM menjadi sinyal QUIT adalah perilaku yang tepat untuk mengubah hard shutdown menjadi shutdown yang anggun.

Namun, melakukan hal ini tampaknya menimbulkan risiko tidak ada penghentian sama sekali dalam beberapa kasus - akar dari bug ini. Pengguna yang mengalami gantung dynos menjalankan Unicorn harus mempertimbangkan bukti dan membuat keputusan sendiri berdasarkan prinsip pertama, bukan hanya dokumentasi.

Winfield
sumber
2
Dokumentasi Heroku masih mencakup " Shutdown yang anggun dengan SIGTERM ", dan saya tidak melihat ada yang menyebutkan tidak perlu lagi melakukan ini pada tumpukan Cedar. Apakah Anda memiliki referensi di mana ini dapat ditemukan?
Dennis
Saya tidak dapat menemukan dokumentasi yang mendukung jawaban ini. Menurut dokumentasi Unicorn dan Heroku, Unicorn masih menggunakan kebalikan dari interpretasi sinyal POSIX.
Josh Kovach
Ini tidak benar. Unicorn masih tidak bisa dimatikan dengan baik tanpa penanganan eksplisit dari sinyal TERM. Artikel Pusat Pengembang yang mendukung ini dapat ditemukan di sini: devcenter.heroku.com/articles/rails-unicorn#config
miring
Saya tahu dokumen Heroku mengatakan Anda harus mencoba menangkap / mengubah sinyal ini. Upaya untuk mematikan dengan baik adalah penyebab utama yang paling mungkin untuk waktu tunggu penghentian.
Winfield