2012-01-15 25 views
12

Ai đó có thể hướng dẫn tôi về cách người lái xe thử lại khi ngoại lệ là bị ném hoặc khi xảy ra lỗi?Điều kiện lỗi và thử lại trong gearman?

Tôi sử dụng ứng dụng khách python trong ứng dụng Django và công nhân của tôi là được khởi xướng làm lệnh Django. Tôi đọc từ điều này blog post mà retries từ điều kiện lỗi không thẳng về phía trước và rằng nó đòi hỏi sys.exit từ phía công nhân.

Điều này đã được khắc phục để thử lại có thể với sendFail hoặc sendException? Ngoài ra hỗ trợ gearman thử lại với thuật toán hàm mũ - giả sử nếu lỗi SMTP xảy ra, thử lại sau 2,4,8,16 giây, v.v ...?

+0

sys.exit() là một ý tưởng tồi với Gearman - thông thường nó sẽ thử lại bất kỳ công việc như vậy mãi mãi (trừ khi bạn có công việc thử lại đặt trên khởi động daemon). Chỉ cần thực hiện 'return stringvar' với bất kỳ trạng thái/kết quả nào từ công việc (ví dụ: nhập vào hàng DB hoặc bộ nhớ cache có thông tin thực.) – RichVel

Trả lời

25

Theo sự hiểu biết của tôi, Gearman sử dụng phương pháp "không phải của doanh nghiệp của tôi" - ví dụ: nó không can thiệp vào công việc được thực hiện, trừ khi người lao động gặp sự cố. Bất kỳ thông báo thành công/thất bại nào được cho là được xử lý bởi máy khách, không phải máy chủ của Gearman.

Trong công việc tiền cảnh, điều này ngụ ý rằng tất cả sendFail()/sendException() và khác send*() được chuyển hướng tới khách hàng và tùy thuộc vào khách hàng để quyết định có nên thử lại công việc hay không. Điều này có ý nghĩa như đôi khi bạn có thể không cần phải thử lại.

Trong các công việc nền, tất cả các chức năng send*() mất ý nghĩa của chúng, vì không có ứng dụng khách nào có thể nghe các cuộc gọi lại. Kết quả là, các tin nhắn được gửi sẽ bị bỏ qua bởi Gearman. Điều kiện duy nhất mà công việc sẽ được thử lại là khi nhân viên bị treo (có thể được mô phỏng bằng lệnh exit(XX), trong đó XX là giá trị khác 0). Điều này, tất nhiên, không phải là một cái gì đó bạn muốn làm, bởi vì công nhân thường được coi là các quy trình chạy dài, không phải là các quy trình phải được khởi động lại sau mỗi công việc không thành công.

Cá nhân, tôi đã giải quyết vấn đề này bằng cách mở rộng lớp GearmanJob mặc định, nơi tôi chặn các cuộc gọi đến các chức năng send*() và sau đó thực hiện lại cơ chế thử lại. Về cơ bản, tôi vượt qua tất cả các dữ liệu liên quan đến thử lại (số lần thử lại tối đa, số lần đã thử lại) cùng với khối lượng công việc và sau đó tự xử lý mọi thứ. Đó là một chút cồng kềnh, nhưng tôi hiểu lý do tại sao Gearman hoạt động theo cách này - nó chỉ cho phép bạn xử lý tất cả các logic ứng dụng.

Cuối cùng, liên quan đến khả năng thử lại công việc với thời gian chờ theo hàm mũ (hoặc bất kỳ thời gian chờ nào cho vấn đề đó). Gearman có một tính năng để thêm các công việc bị trì hoãn (tìm SUBMIT_JOB_EPOCH trong protocol documentation), nhưng tôi không chắc chắn về trạng thái của nó - phần mở rộng PHP và, tôi nghĩ, mô-đun Python không hỗ trợ nó và các tài liệu nói rằng nó có thể được loại bỏ tương lai. Nhưng tôi hiểu nó hoạt động tại thời điểm này - bạn chỉ cần gửi yêu cầu ổ cắm thô đến Gearman để làm cho nó xảy ra (và phần mũ cũng phải được thực hiện trên mặt của bạn, quá).

Tuy nhiên, this blog post cho rằng SUBMIT_JOB_EPOCH triển khai không mở rộng tốt. Ông sử dụng node.js và setTimeout() để làm cho nó hoạt động, tôi đã nhìn thấy những người khác sử dụng tiện ích unix at để làm như vậy. Trong bất kỳ cách nào - Gearman sẽ không làm điều đó cho bạn. Nó sẽ tập trung vào độ tin cậy, nhưng sẽ cho phép bạn tập trung vào tất cả các logic.

+5

Tôi biết đó là câu trả lời cho câu hỏi cũ, nhưng tôi đã thấy nhiều người đấu tranh với cùng một vấn đề và tôi tin rằng nó có giá trị cung cấp hình ảnh đầy đủ một lần và cho tất cả. – Aurimas