Làm thế nào để Waitress xử lý các nhiệm vụ đồng thời?


8

Tôi đang cố gắng xây dựng một máy chủ web python bằng Django và Waitress, nhưng tôi muốn biết Waitress xử lý các yêu cầu đồng thời như thế nào và khi nào việc chặn có thể xảy ra.


Mặc dù tài liệu Waitress đề cập rằng có nhiều luồng công nhân có sẵn, nhưng nó không cung cấp nhiều thông tin về cách chúng được thực hiện và cách con trăn GIL ảnh hưởng đến chúng (nhấn mạnh vào chính tôi):

Khi một kênh xác định máy khách đã gửi ít nhất một yêu cầu HTTP hợp lệ đầy đủ, nó sẽ lên lịch cho một "tác vụ" với "bộ điều phối luồng". Bộ điều phối luồng duy trì một nhóm các luồng công nhân cố định có sẵn để thực hiện công việc của máy khách (theo mặc định, 4 luồng). Nếu một luồng công nhân có sẵn khi một tác vụ được lên lịch, thì luồng công nhân sẽ chạy tác vụ đó. Tác vụ có quyền truy cập vào kênh và có thể ghi lại vào bộ đệm đầu ra của kênh. Khi tất cả các luồng công nhân đang được sử dụng , các tác vụ theo lịch trình sẽ chờ trong hàng đợi để một luồng công nhân có sẵn.

Dường như không có nhiều thông tin về Stackoverflow. Từ câu hỏi "Công nhân không đồng bộ gthread của Gunicorn có giống với Waitress không?" :

Waitress có một luồng async chính để đệm các yêu cầu và liệt kê từng yêu cầu tới một trong các luồng worker worker của nó khi I / O yêu cầu kết thúc.


Những tuyên bố này không đề cập đến GIL (ít nhất là theo sự hiểu biết của tôi) và thật tuyệt nếu ai đó có thể giải thích nhiều hơn về cách các chủ đề công nhân làm việc cho Waitress. Cảm ơn!


Bạn đã có được một giải pháp cho điều này?
biến

@variable Thật không may. Từ việc nhìn thoáng qua người phục vụ github repo , có vẻ như họ không làm gì để làm việc xung quanh GIL, mặc dù tôi không thể nói chắc chắn. Hiện tại, nhóm của tôi đang gắn bó với Waitress vì ứng dụng của chúng tôi không yêu cầu mức độ tương tranh quá cao.
MoltenMuffins

Khi sử dụng máy chủ dev jar mặc định, chúng ta có thể đặt số lượng quy trình bằng werkzeug.palletsprojects.com/en/1.0.x/serving/ Lỗi - điều này không tồn tại trong phục vụ bàn?
biến

Có, số lượng công nhân có thể được cấu hình nhưng điều này không nói lên hành vi chặn của họ
MoltenMuffins

Nếu một công nhân có nghĩa là một quy trình độc lập, thì điều này có nghĩa là mỗi quy trình có trình thông dịch python riêng. phải không
biến

Câu trả lời:


1

Đây là cách các máy chủ không đồng bộ hướng sự kiện thường hoạt động:

  • Bắt đầu một quá trình và lắng nghe các yêu cầu đến. Việc sử dụng API thông báo sự kiện của hệ điều hành giúp cho việc phục vụ hàng ngàn khách hàng từ một luồng / quy trình đơn giản trở nên rất dễ dàng.
  • Vì chỉ có một quy trình quản lý tất cả các kết nối, bạn không muốn thực hiện bất kỳ tác vụ chậm (hoặc chặn) nào trong quy trình này. Bởi vì sau đó nó sẽ chặn chương trình cho mọi khách hàng.
  • Để thực hiện các tác vụ chặn, máy chủ ủy thác các tác vụ cho "công nhân". Công nhân có thể là các luồng (chạy trong cùng một tiến trình) hoặc các tiến trình riêng biệt (hoặc các quy trình con). Bây giờ quy trình chính có thể tiếp tục phục vụ khách hàng trong khi công nhân thực hiện các nhiệm vụ chặn.

Làm thế nào để Waitress xử lý các nhiệm vụ đồng thời?

Khá giống như cách tôi vừa mô tả ở trên. Và đối với công nhân, nó tạo ra các luồng, không phải các quy trình.

con trăn GIL ảnh hưởng đến chúng như thế nào

Phục vụ sử dụng chủ đề cho công nhân. Vì vậy, vâng, họ bị ảnh hưởng bởi GIL ở chỗ họ không thực sự đồng thời mặc dù họ có vẻ như vậy. "Không đồng bộ" là thuật ngữ chính xác.

Các luồng trong Python chạy bên trong một tiến trình, trên một lõi CPU và không chạy song song. Một luồng thu được GIL trong một khoảng thời gian rất nhỏ và thực thi mã của nó và sau đó GIL được một luồng khác thu được.

Nhưng vì GIL được phát hành trên I / O mạng, quy trình mẹ sẽ luôn có được GIL bất cứ khi nào có sự kiện mạng (như yêu cầu đến) và bằng cách này bạn có thể yên tâm rằng GIL sẽ không ảnh hưởng đến các hoạt động bị ràng buộc của mạng ( như nhận yêu cầu hoặc gửi phản hồi).

Mặt khác, các quy trình Python thực sự đồng thời: chúng có thể chạy song song trên nhiều lõi. Nhưng Waitress không sử dụng các quy trình.

Bạn có nên lo lắng?

Nếu bạn chỉ thực hiện các tác vụ chặn nhỏ như đọc / ghi cơ sở dữ liệu và chỉ phục vụ vài trăm người dùng mỗi giây, thì việc sử dụng các luồng không thực sự tệ đến thế.

Để phục vụ một khối lượng lớn người dùng hoặc thực hiện các tác vụ chặn chạy dài, bạn có thể xem xét sử dụng hàng đợi tác vụ bên ngoài như Celery . Điều này sẽ tốt hơn nhiều so với việc tự sinh sản và quản lý các quy trình.


Có phải tốt hơn để sử dụng một máy chủ ứng dụng dựa trên quy trình để xử lý nhiều yêu cầu hơn?
biến

@variable Nếu bạn đang thực hiện các tác vụ ràng buộc CPU (còn gọi là chặn các tác vụ) như tính toán nặng, thì, vâng, sử dụng công nhân xử lý sẽ tốt hơn. Nhưng có những dự án như Celery giúp bạn chạy các nhiệm vụ chặn trong "hàng đợi nhiệm vụ" riêng biệt. Vì vậy, không quan trọng bạn đang sử dụng loại máy chủ ứng dụng nào. Nhưng chỉ để thực hiện các tác vụ ràng buộc mạng (như chờ yêu cầu của khách hàng hoặc tìm nạp dữ liệu từ API của bên thứ ba) thì bạn không cần nhân viên.
xyres

@variable Và nếu máy chủ "dựa trên quy trình", bạn có nghĩa là một máy chủ tạo quy trình mới cho mọi yêu cầu, thì không, đó là cách ít có khả năng mở rộng nhất. Cách hiệu quả nhất (và phổ biến) là những gì tôi đã mô tả ở đầu câu trả lời: phục vụ tất cả các yêu cầu từ một quy trình chính duy nhất và ủy thác các nhiệm vụ chặn cho công nhân (luồng hoặc quy trình con).
xyres

Bằng cách "ủy thác các nhiệm vụ chặn cho công nhân (luồng hoặc quy trình con)" - ý bạn là Celery?
biến

@variable Bạn có thể tự mình duy trì một nhóm các quy trình con trong chương trình của mình và chuyển cho chúng các nhiệm vụ chặn. Đối với các dự án nhỏ hơn phương pháp này là ổn. Cần tây sẽ cung cấp cho bạn lợi thế của khả năng mở rộng dễ dàng. Bạn có thể dễ dàng chạy nó trên một máy chủ hoặc một cụm máy chủ tùy theo nhu cầu của bạn. Đối với các dự án nhỏ hơn, nó có thể là một quá mức cần thiết, mặc dù. Bạn có thể chuyển sang Celery nếu và khi bạn cần.
xyres
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.