2013-02-25 31 views
9

Khi chúng tôi khởi động lại hoặc triển khai, chúng tôi nhận được một số công việc Resque trong hàng đợi không thành công với Resque::TermException (SIGTERM) hoặc Resque::DirtyExit.Phục hồi sạch từ Resque :: TermException hoặc SIGTERM trên Heroku

Chúng tôi đang sử dụng mới TERM_CHILD=1 RESQUE_TERM_TIMEOUT=10 trong Procfile của chúng tôi để dòng người lao động của chúng tôi trông giống như:

worker: TERM_CHILD=1 RESQUE_TERM_TIMEOUT=10 bundle exec rake environment resque:work QUEUE=critical,high,low 

Chúng tôi cũng đang sử dụng resque-retry mà tôi nghĩ có thể tự động thử lại trên hai trường hợp ngoại lệ này? Nhưng có vẻ như không.

Vì vậy, tôi đoán hai câu hỏi:

  1. Chúng tôi bằng tay có thể giải cứu từ Resque::TermException trong từng công việc, và sử dụng để sắp xếp lại công việc. Nhưng liệu có cách nào sạch sẽ để làm điều này cho mọi công việc? Ngay cả một miếng vá khỉ.
  2. Không nên khởi động lại, thử lại tự động thử lại các tính năng này? Bạn có thể nghĩ ra bất kỳ lý do gì tại sao nó không?

Cảm ơn!

Chỉnh sửa: Nhận tất cả công việc cần hoàn thành trong chưa đầy 10 giây có vẻ không hợp lý về quy mô. Có vẻ như cần phải có một cách để tự động sắp xếp lại các công việc này khi ngoại lệ Resque :: DirtyExit được chạy.

Trả lời

1

Công việc khôi phục của bạn có mất hơn 10 giây để hoàn tất không? Nếu các công việc hoàn thành trong vòng 10 giây sau khi SIGTERM ban đầu được gửi, bạn sẽ ổn. Cố gắng chia nhỏ công việc thành những phần nhỏ hơn để hoàn thành nhanh hơn.

Ngoài ra, bạn có thể có nhân viên của bạn lại enqueue công việc làm một cái gì đó như thế này: https://gist.github.com/mrrooijen/3719427

+0

upvoted và chấp nhận - Tôi thành thật không chắc chắn nếu chúng ta có thể nhận được tất cả dưới 10 giây mặc dù. Chúng tôi có một số hàng xuất khẩu lớn vv mà cần phải tạo ra một tập tin. Tái enqueueing có vẻ như nó giải quyết điều này mặc dù? Bạn có thể chia sẻ sự khác nhau giữa 'Resque :: TermException' và' Resque :: DirtyExit' hay không. Tôi có một giải cứu trong đó cho 'Resque :: DirtyExit' nhưng nó không có vẻ luôn luôn tái enqueue. Cảm ơn! –

+0

Là một bản cập nhật, họ kỳ lạ không giải cứu những ngoại lệ đó một cách rõ ràng đôi khi mặc dù có 'giải cứu Resque :: DirtyExit' trong công việc. Tôi đã không thể tìm ra lý do tại sao. Điều này làm cho công việc của chúng tôi không đáng tin cậy vì chúng tôi vẫn tìm thấy chúng trong hàng đợi không thành công với ngoại lệ Resque :: DirtyExit. Nó thực sự trở thành một vấn đề –

+0

Ai đó có thể giới thiệu cách nhân viên xử lý SIGTERM bên trong nhân viên để người lao động có thể tự tắt nó không? Ví dụ, công nhân (resque) cũng bẫy SIGTERM và đặt một số biến mà mã lặp định kỳ kiểm tra? Im giả định rằng TermException hoặc DirtyException chỉ được gọi sau RESQUE_TERM_TIMEOUT secnds. –

1
  1. Chúng ta có thể tự giải cứu khỏi Resque :: TermException trong từng công việc, và sử dụng để sắp xếp lại công việc . Nhưng liệu có cách nào để làm một cách sạch sẽ để thực hiện điều này cho tất cả các công việc? Ngay cả một miếng vá khỉ.

Ngoại lệ Resque::DirtyExit được nâng lên khi công việc được giết với tín hiệu SIGTERM. Công việc không có cơ hội để bắt ngoại lệ vì bạn có thể read here.

  1. Không nên khởi động lại, thử lại tự động thử lại các tính năng này? Bạn có thể nghĩ ra bất kỳ lý do gì tại sao nó không?

Bạn không thấy lý do tại sao nó không nên, được lên lịch chạy? Nếu không phải là rake resque:scheduler.

tôi đã viết một bài đăng blog chi tiết xung quanh một số vấn đề tôi đã gần đây với Resque::DirtyExit, có lẽ nó rất hữu ích =>Understanding the Resque internals – Resque::DirtyExit unveiled

0

Tôi cũng đã phải vật lộn với điều này cho một lúc mà không tìm thấy một giải pháp đáng tin cậy.

Một trong số ít giải pháp tôi tìm thấy đang chạy tác vụ cào trên lịch biểu (cron job mỗi 1 phút) tìm kiếm công việc thất bại với Resque :: DirtyExit, thử lại những công việc cụ thể này và xóa những công việc này khỏi thất bại xếp hàng.

Dưới đây là một ví dụ về các nhiệm vụ cào https://gist.github.com/CharlesP/1818418754aec03403b3

Giải pháp này rõ ràng là không tối ưu nhưng cho đến nay đó là giải pháp tốt nhất mà tôi đã tìm thấy để thử lại những việc làm.

2

Tôi cũng gặp sự cố này. Nó chỉ ra rằng Heroku gửi tín hiệu SIGTERM để không chỉ quá trình cha mẹ, nhưng tất cả các quá trình chia hai. Đây không phải là logic mà Resque mong đợi làm cho số RESQUE_PRE_SHUTDOWN_TIMEOUT bị bỏ qua, buộc các công việc phải thực thi mà không cần thời gian để hoàn thành công việc.

Heroku cung cấp cho người lao động 30 tuổi để tắt máy một cách duyên dáng sau khi phát hành SIGTERM. Trong hầu hết các trường hợp, điều này là rất nhiều thời gian để hoàn thành một công việc với một số thời gian đệm còn lại để requeue công việc để Resque nếu công việc không thể hoàn thành. Tuy nhiên, cho tất cả thời gian này được sử dụng, bạn cần phải đặt RESQUE_PRE_SHUTDOWN_TIMEOUTRESQUE_TERM_TIMEOUT env vars cũng như bản vá Resque để trả lời chính xác SIGTERM đang được gửi đến các quy trình được chia hai.

Dưới đây là một viên ngọc để vá resque và giải thích vấn đề này chi tiết hơn:

https://github.com/iloveitaly/resque-heroku-signals

+0

Đây là giải thích đúng. Cảm ơn @iloveitaly – Yoni

Các vấn đề liên quan