ข้อผิดพลาดการหมดเวลาใช้งานของ Gunicorn


182

ฉันมีการติดตั้ง gunicorn ด้วยการเชื่อมต่อกับคนงาน 3 คน 30 คนและใช้คลาสผู้ทำงานอีเว้นท์ มันตั้งค่าไว้ด้านหลัง Nginx หลังจากคำขอทุกสองสามครั้งฉันเห็นสิ่งนี้ในบันทึก

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

ทำไมสิ่งนี้จึงเกิดขึ้น ฉันจะรู้ได้อย่างไรว่าเกิดอะไรขึ้น

ขอบคุณ


2
คุณสามารถแก้ไขปัญหาได้หรือไม่ โปรดแบ่งปันความคิดของคุณขณะที่ฉันยังติดอยู่กับมัน Gunicorn==19.3.1และgevent==1.0.1
Black_Rider

2
พบวิธีแก้ปัญหาสำหรับมัน เพิ่มการหมดเวลาเป็นค่าที่มีขนาดใหญ่มากและจากนั้นฉันก็สามารถเห็นการติดตามสแต็ก
Black_Rider

คำตอบ:


156

เรามีปัญหาเดียวกันกับการใช้ Django + nginx + gunicorn จากเอกสารของ Gunicorn เราได้กำหนดค่าการหมดเวลาอย่างงดงามซึ่งแทบไม่แตกต่างกันเลย

หลังจากการทดสอบบางอย่างเราพบวิธีแก้ปัญหาพารามิเตอร์การกำหนดค่าคือ: หมดเวลา (และไม่ใช่การหมดเวลาที่สง่างาม) มันทำงานเหมือนนาฬิกา ..

ดังนั้นทำ:

1) เปิดไฟล์การกำหนดค่าของ gunicorn

2) ตั้งค่า TIMEOUT เป็นสิ่งที่คุณต้องการ - ค่าเป็นวินาที

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
ขอบคุณนี่คือคำตอบที่ถูกต้อง จากนั้นเพื่อประหยัดทรัพยากรด้วยการเชื่อมต่อพร้อมกันจำนวนมาก: pip install geventจากนั้นworker_class geventในไฟล์กำหนดค่าของคุณหรือ-k geventบนบรรทัดคำสั่ง
little_birdie

2
ฉันกำลังทำงานกับหัวหน้างานดังนั้นเพิ่มไปที่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


21

เรียก Gunicorn --log-level=DEBUGกับ

ควรให้แอปติดตามสแต็กกับคุณ


41
มันไม่ได้อยู่ในกรณีของฉัน
Joe

16
ได้แล้ว--log-level debug
psychok7

4
ฉันชอบที่จะได้รับ stracktrace แต่ไม่มีพวกเขาทำงานที่นี่โดยใช้ gunicorn 19.4.5 สิ่งที่ดีบั๊กจะปรากฏขึ้นดังนั้นฉันเดาว่าการตั้งค่าสถานะเป็นที่รู้จัก แต่ไม่ใช่สแต็คตามเวลาที่หมดไป
orzel


6

คุณต้องใช้คลาสประเภทคนงานคนอื่นแบบอะซิงก์เช่นgeventหรือทอร์นาโดดูคำอธิบายเพิ่มเติมนี้: คำอธิบายแรก:

คุณอาจต้องการติดตั้ง Eventlet หรือ Gevent หากคุณคาดหวังว่ารหัสแอปพลิเคชันของคุณอาจต้องหยุดชั่วคราวเป็นระยะเวลานานในระหว่างการประมวลผลคำขอ

อันที่สอง :

คนงานซิงโครนัสเริ่มต้นถือว่าแอปพลิเคชันของคุณเป็นทรัพยากรที่ถูกผูกไว้ในแง่ของ CPU และแบนด์วิดท์เครือข่าย โดยทั่วไปหมายความว่าแอปพลิเคชันของคุณไม่ควรทำสิ่งใดที่ต้องใช้เวลานาน ตัวอย่างเช่นคำขอไปยังอินเทอร์เน็ตตรงตามเกณฑ์นี้ ณ จุดหนึ่งเครือข่ายภายนอกจะล้มเหลวในลักษณะที่ลูกค้าจะพะเนินเทินทึกบนเซิร์ฟเวอร์ของคุณ


ฉันจะใช้ประโยชน์จากคลาสพนักงานที่แตกต่างกันอย่างไร
Frederick Nord

6

ฉันมีปัญหาที่คล้ายกันมากฉันลองใช้ "runserver" เพื่อดูว่าฉันสามารถหาอะไรได้บ้าง แต่ทั้งหมดที่ฉันมีคือข้อความ Killed

ดังนั้นฉันคิดว่าอาจเป็นปัญหาทรัพยากรและฉันไปข้างหน้าเพื่อให้ RAM เพิ่มเติมกับอินสแตนซ์และทำงานได้


1
ฉันได้เห็นปัญหานี้แม้กับ gevent และการตั้งค่าการหมดเวลาอย่างถูกต้องหน่วยความจำไม่
เพียงพอ

6

WORKER TIMEOUTหมายความว่าแอปพลิเคชันของคุณไม่สามารถตอบสนองต่อคำขอภายในระยะเวลาที่กำหนด คุณสามารถตั้งค่านี้โดยใช้การตั้งค่า gunicorn หมดเวลา แอปพลิเคชั่นบางตัวต้องการเวลาในการตอบสนองมากกว่าแอปอื่น

สิ่งที่อาจส่งผลกระทบต่อสิ่งนี้คือการเลือกประเภทของผู้ปฏิบัติงาน

คนงานซิงโครนัสเริ่มต้นถือว่าแอปพลิเคชันของคุณมีทรัพยากรในแง่ของ CPU และแบนด์วิดท์เครือข่าย โดยทั่วไปหมายความว่าแอปพลิเคชันของคุณไม่ควรทำสิ่งใดที่ต้องใช้เวลานาน ตัวอย่างของสิ่งที่ต้องใช้ระยะเวลาที่ไม่ได้กำหนดคือคำขอไปยังอินเทอร์เน็ต ณ จุดหนึ่งเครือข่ายภายนอกจะล้มเหลวในลักษณะที่ลูกค้าจะพะเนินเทินทึกบนเซิร์ฟเวอร์ของคุณ ดังนั้นในแง่นี้เว็บแอปพลิเคชันใด ๆ ที่ส่งคำขอไปยัง APIs จะได้รับประโยชน์จากพนักงานอะซิงโครนัส

เมื่อฉันมีปัญหาเช่นเดียวกับของคุณ (ฉันกำลังพยายามปรับใช้แอปพลิเคชันของฉันโดยใช้ Docker Swarm) ฉันพยายามเพิ่มการหมดเวลาและใช้คลาสคนงานประเภทอื่น แต่ทั้งหมดล้มเหลว

และทันใดนั้นฉันก็รู้ว่าฉัน จำกัด ทรัพยากรของฉันไว้ต่ำเกินไปสำหรับบริการในไฟล์การเขียนของฉัน นี่คือสิ่งที่ชะลอการสมัครในกรณีของฉัน

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

ดังนั้นฉันขอแนะนำให้คุณตรวจสอบสิ่งที่ชะลอการสมัครของคุณในสถานที่แรก


4

จุดสิ้นสุดนี้ใช้เวลานานเกินไปหรือไม่

บางทีคุณกำลังใช้ขวดโดยไม่มีการสนับสนุนแบบอะซิงโครนัสดังนั้นทุกคำขอจะบล็อกการโทร หากต้องการสร้างการสนับสนุน async โดยไม่ยากให้เพิ่มgeventปฏิบัติงาน

ด้วย gevent การโทรใหม่จะวางไข่เธรดใหม่และแอปของคุณจะสามารถรับคำขอเพิ่มเติมได้

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

1
บิดง่าย .. ช่วยชีวิตฉันไว้!
penduDev

3

ฉันมีปัญหาเดียวกันใน Docker

ใน Docker ฉันเก็บLightGBMแบบจำลอง + Flaskคำขอการให้บริการ ในฐานะที่เป็นเซิร์ฟเวอร์ HTTP gunicorn 19.9.0ผมใช้ เมื่อฉันเรียกใช้รหัสของฉันในเครื่องแล็ปท็อป Mac ของฉันทุกอย่างทำงานได้สมบูรณ์แบบ แต่เมื่อฉันรันแอพใน Docker คำขอ POST JSON ของฉันถูกแช่แข็งในบางครั้งgunicornคนงานก็ล้มเหลวโดยไม่มี[CRITICAL] WORKER TIMEOUTข้อยกเว้น

ฉันพยายามตันของวิธีการที่แตกต่างกัน worker_class=gthreadแต่เพียงคนเดียวที่ได้รับการแก้ไขปัญหาของฉันได้รับการเพิ่ม

นี่คือการกำหนดค่าที่สมบูรณ์ของฉัน:

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

ตอบโต้คำตอบอื่น ๆ ของคุณเช่นกันคำตอบนี้ไม่เพียงพอ: P
Achala Dissanayake


1

การหมดเวลาเป็นพารามิเตอร์สำคัญสำหรับปัญหานี้

อย่างไรก็ตามมันไม่เหมาะสำหรับฉัน

ฉันพบว่าไม่มีข้อผิดพลาดการหมดเวลาของ gunicorn เมื่อฉันตั้งคนงาน = 1

เมื่อฉันดูรหัสของฉันฉันพบซ็อกเก็ตเชื่อมต่อ (socket.send & socket.recv) ในเซิร์ฟเวอร์ init

socket.recv จะบล็อกรหัสของฉันและนั่นคือเหตุผลที่มันหมดเวลาเสมอเมื่อคนงาน> 1

หวังว่าจะให้แนวคิดบางอย่างกับคนที่มีปัญหากับฉัน


1

สิ่งนี้ใช้ได้กับฉัน:

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

ถ้าคุณมีeventletเพิ่ม:

--worker-class=eventlet

ถ้าคุณมีgeventเพิ่ม:

--worker-class=gevent

0

สำหรับฉันทางออกคือการเพิ่ม--timeout 90ไปยังจุดเข้าใช้งานของฉัน แต่มันไม่ทำงานเพราะฉันได้กำหนดจุดเข้าใช้งานสองรายการจุดหนึ่งใน app.yaml และอีกจุดหนึ่งใน Dockerfile ของฉัน ฉันลบจุดเข้าใช้งานที่ไม่ได้ใช้และเพิ่ม--timeout 90ในส่วนอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.