Tôi đang làm việc trên dịch vụ web được triển khai ở trên cùng của nginx + gunicorn + django. Các khách hàng là các ứng dụng điện thoại thông minh. Ứng dụng cần thực hiện một số cuộc gọi chạy dài tới các API bên ngoài (Facebook, Amazon S3 ...), vì vậy máy chủ chỉ cần gửi hàng công việc đến máy chủ công việc (sử dụng Celery qua Redis).Xử lý hiệu quả các kết nối HTTP chạy dài trong kiến trúc web nginx/gunicorn/django
Bất cứ khi nào có thể, một khi máy chủ đã xếp hàng công việc, nó sẽ trả về ngay lập tức và kết nối HTTP bị đóng. Điều này hoạt động tốt và cho phép máy chủ duy trì tải rất cao.
client server job server
. | |
. | |
|------HTTP request----->| |
| |--------queue job------>|
|<--------close----------| |
. | |
. | |
Nhưng trong một số trường hợp, khách hàng cần nhận kết quả ngay sau khi hoàn thành công việc. Thật không may, không có cách nào máy chủ có thể liên lạc với máy khách khi kết nối HTTP bị đóng. Một giải pháp sẽ là dựa vào ứng dụng khách hàng bỏ phiếu cho máy chủ sau mỗi vài giây cho đến khi công việc được hoàn thành. Tôi muốn tránh giải pháp này, nếu có thể, chủ yếu là vì nó sẽ cản trở tính phản ứng của dịch vụ, và cũng bởi vì nó sẽ tải máy chủ với nhiều yêu cầu thăm dò không cần thiết.
Tóm lại, tôi muốn giữ kết nối HTTP và chạy, không làm gì cả (ngoại trừ việc gửi khoảng trắng mỗi lần để giữ kết nối TCP còn sống, chỉ like Amazon S3 does), cho đến khi hoàn thành công việc và máy chủ trả về kết quả.
client server job server
. | |
. | |
|------HTTP request----->| |
| |--------queue job------>|
|<------keep-alive-------| |
| [...] | |
|<------keep-alive-------| |
| |<--------result---------|
|<----result + close-----| |
. | |
. | |
Làm thế nào tôi có thể thực hiện các kết nối HTTP chạy dài một cách hiệu quả, giả sử máy chủ đang được tải rất cao (nó không phải là trường hợp nào, nhưng mục tiêu để có thể duy trì tải trọng cao nhất có thể, với hàng trăm hoặc hàng ngàn yêu cầu mỗi giây)?
Việc tải công việc thực tế xuống máy chủ khác phải đảm bảo mức sử dụng CPU thấp trên máy chủ, nhưng làm cách nào để tránh các quá trình chồng chất và sử dụng RAM của máy chủ hoặc yêu cầu gửi xuống do quá nhiều kết nối mở?
Điều này có lẽ chủ yếu là vấn đề định cấu hình nginx và gunicorn đúng cách. Tôi đã đọc một chút về async workers based on greenlets in gunicorn: tài liệu cho biết rằng công nhân không đồng bộ được sử dụng bởi "Ứng dụng thực hiện cuộc gọi chặn dài (Tức là, dịch vụ web bên ngoài)", điều này nghe có vẻ hoàn hảo. Nó cũng nói "Nói chung, một ứng dụng sẽ có thể sử dụng các lớp công nhân này mà không có thay đổi". Nghe thật tuyệt. Bất kỳ phản hồi về điều này?
Cảm ơn lời khuyên của bạn.
Bạn đã nghiên cứu các giải pháp 'bỏ phiếu dài' của AJAX cho django chưa? Nó có vẻ như về cơ bản giống nhau. – dgel
Vâng, bạn nói đúng, nó có thể giống nhau. AJAX có nghĩa là javascript ở phía máy khách, đó là nhiều hơn về các trình duyệt web, trong trường hợp của tôi, ứng dụng khách là một ứng dụng softphone. Nhưng phía máy chủ có lẽ gần như giống nhau, ý tưởng tuyệt vời. – MiniQuark