Lỗi thời gian chờ của nhân viên Gunicorn


182

Tôi đã thiết lập gunicorn với 3 công nhân 30 kết nối công nhân và sử dụng lớp workerlet công nhân. Nó được thiết lập đằng sau Nginx. Sau mỗi vài yêu cầu, tôi thấy điều này trong nhật ký.

[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514

Tại sao chuyện này đang xảy ra? Làm thế nào tôi có thể tìm ra những gì đang xảy ra sai?

cảm ơn


2
Bạn đã có thể giải quyết vấn đề? Hãy chia sẻ suy nghĩ của bạn khi tôi cũng bị mắc kẹt với nó. Gunicorn==19.3.1gevent==1.0.1
Black_Rider

2
Tìm thấy giải pháp cho nó. Thời gian chờ tăng lên giá trị rất lớn và sau đó tôi có thể thấy dấu vết ngăn xếp
Black_Rider

Câu trả lời:


156

Chúng tôi đã có cùng một vấn đề khi sử dụng Django + nginx + gunicorn. Từ tài liệu của Gunicorn, chúng tôi đã cấu hình thời gian chờ duyên dáng mà hầu như không có sự khác biệt.

Sau một số thử nghiệm, chúng tôi đã tìm thấy giải pháp, tham số cần cấu hình là: thời gian chờ (Và thời gian chờ không duyên dáng). Nó hoạt động như một chiếc đồng hồ ..

Vì vậy, làm:

1) mở tệp cấu hình gunicorn

2) đặt THỜI GIAN thành những gì bạn cần - giá trị tính bằng giây

NUM_WORKERS=3
TIMEOUT=120

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--log-level=debug \
--bind=127.0.0.1:9000 \
--pid=$PIDFILE

9
Cảm ơn đây là câu trả lời đúng. Và sau đó, để lưu tài nguyên với nhiều kết nối đồng thời: pip install geventsau đó worker_class geventtrong tệp cấu hình của bạn hoặc -k geventtrên dòng lệnh.
little_birdie

2
Đang chạy với người giám sát nên đã thêm nó vào conf.d / app.conf :command=/opt/env_vars/run_with_env.sh /path/to/environment_variables /path/to/gunicorn --timeout 200 --workers 3 --bind unix:/path/to/socket server.wsgi:application
lukik

31

Trên Google Cloud Chỉ cần thêm --timeout 90vào điểm vào trongapp.yaml

entrypoint: gunicorn -b :$PORT main:app --timeout 90

21

Chạy Gunicorn với --log-level=DEBUG.

Nó sẽ cung cấp cho bạn một dấu vết ngăn xếp ứng dụng.


41
Nó không trong trường hợp của tôi.
Joe

16
bây giờ--log-level debug
psychok7

4
Tôi rất muốn có được một chiến lược, nhưng không ai trong số họ làm việc ở đây, sử dụng gunicorn 19.4.5. Công cụ gỡ lỗi được hiển thị, vì vậy tôi đoán cờ đã được nhận ra, nhưng không phải là stacktrace khi hết thời gian.
orzel


6

Bạn cần sử dụng một lớp loại công nhân khác, một lớp không đồng bộ như gevent hoặc tornado xem điều này để được giải thích thêm: Giải thích đầu tiên:

Bạn cũng có thể muốn cài đặt Eventlet hoặc Gevent nếu bạn cho rằng mã ứng dụng của bạn có thể cần phải tạm dừng trong thời gian dài trong quá trình xử lý yêu cầu

Cái thứ hai :

Các nhân viên đồng bộ mặc định cho rằng ứng dụng của bạn bị ràng buộc tài nguyên về CPU và băng thông mạng. Nói chung, điều này có nghĩa là ứng dụng của bạn không nên làm bất cứ điều gì mất một khoảng thời gian không xác định. Chẳng hạn, một yêu cầu tới internet đáp ứng tiêu chí này. Tại một số điểm, mạng bên ngoài sẽ thất bại theo cách mà các máy khách sẽ chồng chất lên các máy chủ của bạn.


Làm thế nào tôi thực sự sử dụng một lớp công nhân khác nhau như vậy?
Frederick Nord

6

Tôi gặp vấn đề rất giống nhau, tôi cũng đã thử sử dụng "máy chủ" để xem liệu tôi có thể tìm thấy gì không nhưng tất cả những gì tôi có là một tin nhắn Killed

Vì vậy, tôi nghĩ rằng nó có thể là vấn đề tài nguyên, và tôi đã đi trước để cung cấp thêm RAM cho ví dụ, và nó đã hoạt động.


1
Tôi đã nhìn thấy vấn đề này ngay cả với gevent và thời gian chờ được đặt chính xác, hết bộ nhớ là vấn đề
bcattle

6

WORKER TIMEOUTcó nghĩa là ứng dụng của bạn không thể đáp ứng yêu cầu trong một khoảng thời gian xác định. Bạn có thể thiết lập điều này bằng cách sử dụng cài đặt thời gian chờ gunicorn . Một số ứng dụng cần nhiều thời gian hơn để đáp ứng hơn một ứng dụng khác.

Một điều khác có thể ảnh hưởng đến điều này là chọn loại công nhân

Các nhân viên đồng bộ mặc định cho rằng ứng dụng của bạn bị ràng buộc tài nguyên về CPU và băng thông mạng. Nói chung, điều này có nghĩa là ứng dụng của bạn không nên làm bất cứ điều gì mất một khoảng thời gian không xác định. Một ví dụ về một cái gì đó mất một lượng thời gian không xác định là một yêu cầu với internet. Tại một số điểm, mạng bên ngoài sẽ thất bại theo cách mà các máy khách sẽ chồng chất lên các máy chủ của bạn. Vì vậy, theo nghĩa này, bất kỳ ứng dụng web nào thực hiện các yêu cầu gửi đến API sẽ được hưởng lợi từ một nhân viên không đồng bộ.

Khi tôi gặp vấn đề tương tự như của bạn (Tôi đã cố gắng triển khai ứng dụng của mình bằng Docker Swarm), tôi đã cố gắng tăng thời gian chờ và sử dụng một loại lớp worker khác. Nhưng tất cả đều thất bại.

Và sau đó tôi đột nhiên nhận ra rằng tôi đang giới hạn tài nguyên của mình quá thấp cho dịch vụ bên trong tệp soạn thảo của mình. Đây là điều làm chậm ứng dụng trong trường hợp của tôi

deploy:
  replicas: 5
  resources:
    limits:
      cpus: "0.1"
      memory: 50M
  restart_policy:
    condition: on-failure

Vì vậy, tôi khuyên bạn nên kiểm tra xem điều gì làm chậm ứng dụng của bạn ngay từ đầu


4

Là điểm cuối này mất quá nhiều thời gian?

Có thể bạn đang sử dụng bình mà không có hỗ trợ đồng bộ, vì vậy mọi yêu cầu sẽ chặn cuộc gọi. Để tạo hỗ trợ async mà không gây khó khăn, hãy thêm geventworker.

Với gevent, một cuộc gọi mới sẽ tạo ra một chuỗi mới và ứng dụng của bạn sẽ có thể nhận được nhiều yêu cầu hơn

pip install gevent
gunicon .... --worker-class gevent

1
tinh chỉnh đơn giản .. tiết kiệm ngày của tôi!
PenduDev

3

Tôi đã có cùng một vấn đề trong Docker.

Trong Docker tôi giữ LightGBMmô hình được đào tạo + Flaskyêu cầu phục vụ. Là máy chủ HTTP tôi đã sử dụng gunicorn 19.9.0. Khi tôi chạy mã cục bộ trên máy tính xách tay Mac của mình, mọi thứ đều hoạt động hoàn hảo, nhưng khi tôi chạy ứng dụng trong Docker, các yêu cầu POST JSON của tôi đã bị đóng băng trong một thời gian, sau đó gunicornworker đã bị lỗi [CRITICAL] WORKER TIMEOUTngoại lệ.

Tôi đã thử rất nhiều cách tiếp cận khác nhau, nhưng cách duy nhất giải quyết được vấn đề của tôi là thêm vào worker_class=gthread.

Đây là cấu hình hoàn chỉnh của tôi:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(q)s" "%(D)s"'
bind = "0.0.0.0:5000"
keepalive = 120
timeout = 120
worker_class = "gthread"
threads = 3

nâng cao một số câu trả lời khác của bạn cũng như câu trả lời này là không đủ: P
Achala Dissanayake


1

thời gian chờ là một tham số quan trọng cho vấn đề này.

Tuy nhiên nó không phù hợp với tôi.

tôi thấy rằng không có lỗi hết thời gian gunicorn khi tôi đặt worker = 1.

Khi tôi nhìn qua mã của mình, tôi đã tìm thấy một số kết nối socket (socket.send & socket.recv) trong máy chủ init.

socket.recv sẽ chặn mã của tôi và đó là lý do tại sao nó luôn hết thời gian khi công nhân> 1

hy vọng sẽ đưa ra một số ý tưởng cho những người có vấn đề với tôi


1

Điều này làm việc cho tôi:

gunicorn app:app -b :8080 --timeout 120 --workers=3 --threads=3 --worker-connections=1000

Nếu bạn có eventletthêm:

--worker-class=eventlet

Nếu bạn có geventthêm:

--worker-class=gevent

0

Đối với tôi, giải pháp là thêm --timeout 90vào điểm vào của tôi, nhưng nó không hoạt động vì tôi đã xác định HAI điểm nhập cảnh, một điểm trong app.yaml và một điểm khác trong Dockerfile của tôi. Tôi đã xóa điểm nhập không sử dụng và thêm --timeout 90vào điểm khác.

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.