Gunicorn: مهلة العامل الناقد عند تشغيل تطبيق Flask

تم إنشاؤها على ٥ يونيو ٢٠١٨  ·  82تعليقات  ·  مصدر: benoitc/gunicorn

يبدو أنه كان هناك بالفعل العديد من التقارير المتعلقة بالخطأ [CRITICAL] WORKER TIMEOUT ولكنه يستمر في الظهور. ها هي مشكلتي.

أنا أقوم بتشغيل تطبيق Flask hello world هذا.

from flask import Flask
application = Flask(__name__)

@application.route('/')
def hello_world():
    return 'Hello, World!'

الأمر gunicorn هو هذا:

gunicorn -b 0.0.0.0:5000 --log-level=debug hello

وهذا هو إخراج وحدة التحكم:

[2018-06-05 14:56:21 +0200] [11229] [INFO] Starting gunicorn 19.8.1
[2018-06-05 14:56:21 +0200] [11229] [DEBUG] Arbiter booted
[2018-06-05 14:56:21 +0200] [11229] [INFO] Listening at: http://0.0.0.0:5000 (11229)
[2018-06-05 14:56:21 +0200] [11229] [INFO] Using worker: sync
[2018-06-05 14:56:21 +0200] [11232] [INFO] Booting worker with pid: 11232
[2018-06-05 14:56:21 +0200] [11229] [DEBUG] 1 workers
[2018-06-05 14:56:32 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:56:57 +0200] [11232] [DEBUG] Closing connection. 
[2018-06-05 14:57:16 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:57:47 +0200] [11229] [CRITICAL] WORKER TIMEOUT (pid:11232)
[2018-06-05 14:57:47 +0200] [11232] [INFO] Worker exiting (pid: 11232)
[2018-06-05 14:57:47 +0200] [11324] [INFO] Booting worker with pid: 11324

هل يمكنك أن تشرح بوضوح لماذا أتلقى الخطأ وما إذا كان متوقعًا في هذا المثال؟ كيف أصلحه أو إذا كان سلوكًا متوقعًا فلماذا خطأ فادح إذن؟

Investigation unconfirmed

التعليق الأكثر فائدة

استخدام gunicorn مع gevent لم يصلح الخطأ.

ال 82 كومينتر

الخطأ غير متوقع ، لكن لا يوجد شيء من مثالك يوضح سبب حدوثه. أخبرنا المزيد عن بيئتك.

  • ما هو العميل المستخدم للاتصال بـ Gunicorn؟
  • ما هو الوكيل العكسي ، إن وجد ، المستخدم للاتصال بـ Gunicorn؟

أخبرنا المزيد عن بيئتك.

  • ما هو العميل المستخدم للاتصال بـ Gunicorn؟
    => لقد أرسلت للتو طلبًا من Chromium: http: // localhost : 5000 /
  • ما هو الوكيل العكسي ، إن وجد ، المستخدم للاتصال بـ Gunicorn؟
    => لا يوجد وكيل ، فقط Gunicorn + Flask

لقد أعدت للتو المشكلة في إعداد جديد تمامًا ، وإليك الخطوات:

mkdir gunicorn
cd gunicorn/
pipenv --python 3.6
pipenv install flask
pipenv install gunicorn
vim hello.py
pipenv shell
gunicorn -b 0.0.0.0:5000 --log-level=debug hello

hello.py هو بالضبط نفس تطبيق Flask الذي نشرته في التقرير الأولي.
أدناه هو السجل الكامل.

~$ gunicorn -b 0.0.0.0:5000 --log-level=debug hello
[2018-06-06 09:16:21 +0200] [19829] [DEBUG] Current configuration:
  config: None
  bind: ['0.0.0.0:5000']
  backlog: 2048
  workers: 1
  worker_class: sync
  threads: 1
  worker_connections: 1000
  max_requests: 0
  max_requests_jitter: 0
  timeout: 30
  graceful_timeout: 30
  keepalive: 2
  limit_request_line: 4094
  limit_request_fields: 100
  limit_request_field_size: 8190
  reload: False
  reload_engine: auto
  reload_extra_files: []
  spew: False
  check_config: False
  preload_app: False
  sendfile: None
  reuse_port: False
  chdir: /home/dima/work/gunicorn
  daemon: False
  raw_env: []
  pidfile: None
  worker_tmp_dir: None
  user: 1000
  group: 985
  umask: 0
  initgroups: False
  tmp_upload_dir: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  forwarded_allow_ips: ['127.0.0.1']
  accesslog: None
  disable_redirect_access_to_syslog: False
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  errorlog: -
  loglevel: debug
  capture_output: False
  logger_class: gunicorn.glogging.Logger
  logconfig: None
  logconfig_dict: {}
  syslog_addr: udp://localhost:514
  syslog: False
  syslog_prefix: None
  syslog_facility: user
  enable_stdio_inheritance: False
  statsd_host: None
  statsd_prefix: 
  proc_name: None
  default_proc_name: hello
  pythonpath: None
  paste: None
  on_starting: <function OnStarting.on_starting at 0x7f9757112d08>
  on_reload: <function OnReload.on_reload at 0x7f9757112e18>
  when_ready: <function WhenReady.when_ready at 0x7f9757112f28>
  pre_fork: <function Prefork.pre_fork at 0x7f9756c230d0>
  post_fork: <function Postfork.post_fork at 0x7f9756c231e0>
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f9756c232f0>
  worker_int: <function WorkerInt.worker_int at 0x7f9756c23400>
  worker_abort: <function WorkerAbort.worker_abort at 0x7f9756c23510>
  pre_exec: <function PreExec.pre_exec at 0x7f9756c23620>
  pre_request: <function PreRequest.pre_request at 0x7f9756c23730>
  post_request: <function PostRequest.post_request at 0x7f9756c237b8>
  child_exit: <function ChildExit.child_exit at 0x7f9756c238c8>
  worker_exit: <function WorkerExit.worker_exit at 0x7f9756c239d8>
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f9756c23ae8>
  on_exit: <function OnExit.on_exit at 0x7f9756c23bf8>
  proxy_protocol: False
  proxy_allow_ips: ['127.0.0.1']
  keyfile: None
  certfile: None
  ssl_version: 2
  cert_reqs: 0
  ca_certs: None
  suppress_ragged_eofs: True
  do_handshake_on_connect: False
  ciphers: TLSv1
  raw_paste_global_conf: []
[2018-06-06 09:16:21 +0200] [19829] [INFO] Starting gunicorn 19.8.1
[2018-06-06 09:16:21 +0200] [19829] [DEBUG] Arbiter booted
[2018-06-06 09:16:21 +0200] [19829] [INFO] Listening at: http://0.0.0.0:5000 (19829)
[2018-06-06 09:16:21 +0200] [19829] [INFO] Using worker: sync
[2018-06-06 09:16:21 +0200] [19832] [INFO] Booting worker with pid: 19832
[2018-06-06 09:16:22 +0200] [19829] [DEBUG] 1 workers
[2018-06-06 09:16:48 +0200] [19832] [DEBUG] GET /
[2018-06-06 09:17:19 +0200] [19829] [CRITICAL] WORKER TIMEOUT (pid:19832)
[2018-06-06 09:17:19 +0200] [19832] [INFO] Worker exiting (pid: 19832)
[2018-06-06 09:17:19 +0200] [19872] [INFO] Booting worker with pid: 19872
^C[2018-06-06 09:17:26 +0200] [19829] [INFO] Handling signal: int
[2018-06-06 09:17:26 +0200] [19872] [INFO] Worker exiting (pid: 19872)
[2018-06-06 09:17:26 +0200] [19829] [INFO] Shutting down: Master
~$ pip list
Package      Version
------------ -------
click        6.7    
Flask        1.0.2  
gunicorn     19.8.1 
itsdangerous 0.24   
Jinja2       2.10   
MarkupSafe   1.0    
pip          10.0.1 
setuptools   39.2.0 
Werkzeug     0.14.1 
wheel        0.31.1

bigunyak أعتقد أنه بسبب المهلة الافتراضية ، فقد ظل موظفك صامتًا لمدة 30 ثانية. http://docs.gunicorn.org/en/stable/settings.html#timeout

من سجلك ،

[2018-06-05 14:57:16 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:57:47 +0200] [11229] [CRITICAL] WORKER TIMEOUT (pid:11232)
[2018-06-06 09:16:48 +0200] [19832] [DEBUG] GET /
[2018-06-06 09:17:19 +0200] [19829] [CRITICAL] WORKER TIMEOUT (pid:19832)

أرى نفس الشيء: ينتهي المهلة الزمنية للعمال حتى عند عدم تقديم أي طلبات ، مع عامل المزامنة.
لهذا المعنى ، فإن سجل المستوى الحرج محير للغاية.

حاول استخدام عامل Gevent يمكن أن يحل هذا.

لهذا المعنى ، فإن سجل المستوى الحرج محير للغاية.

بالضبط ، كان هذا هو سؤالي الأصلي: إذا كان سلوكًا متوقعًا ، فلماذا الخطأ الفادح إذن؟
سيكون من الجيد أيضًا الحصول على بعض المعلومات الأساسية حول سبب حاجة العمال إلى إعادة التشغيل ، وربما يمكن إضافة ذلك إلى مستند التصميم .

أرى هذا أيضًا (تمت إعادة إنتاجه باستخدام examples/test.py مع gunicorn test:app -b localhost:9595 --log-level=debug --timeout=5 ) وأوافق على أن المستوى الحرج محير بعض الشيء. سأكون على ما يرام تغييره إلى مستوى التصحيح. benoitc tilgovi ما رأيك؟

أعتقد أن مستوى المعلومات قد يكون أفضل قليلاً.

كان لدي نفس الشيء مع MSYS2 على Win10 ولكن في النهاية يمكن حلها.

في الإخطار () بـ ... \ gunicorn \ worker \ workertmp.py ، يتم استخدام os.fchmod في الأصل. لكنها لا تعمل في MSYS. بدلاً من os.fchmod ، استخدمت os.utime. تم اتباع الكود. أعتقد أنه يمكن أن يعمل لجميع المنصات.

    def notify(self):
        try:
            self.spinner = (self.spinner + 1) % 2
            os.fchmod(self._tmp.fileno(), self.spinner)
            if PLATFORM.startswith('MSYS') :
                os.utime(self._tmp.fileno(), None)
        except AttributeError:
            # python < 2.6
            self._tmp.truncate(0)
            os.write(self._tmp.fileno(), b"X")

berkerpeksag لا أتوقع خروج العامل لأنه لا توجد طلبات. يجب ألا يحدث هذا الخطأ إلا إذا ظل العامل مشغولاً لبعض الوقت> حتى انتهاء المهلة. لذا فإن الخطأ فادح. يجب علينا تحسين الوثائق IMO لتقديم المزيد من حالات الاستخدام والردود على مثل هذه الأخطاء.

إذا استمر حدوث الخطأ عندما لا يكون العامل مشغولاً ، فهناك شيء آخر يحدث وربما يكون لدينا خطأ.

[تعديل]
نفس الخطأ بالنسبة لي.
مع Django 1.10 / Gunicorn 19.6.0 / Python 2.7.15 في python2.7-alpine على Debian 8.8 و stock kernel 3.16 ، كان كل شيء يعمل بشكل جيد.
بعد التحديث إلى Django 1.11 و Gunicorn 19.8.1 ، استمر العمال في الفشل في التمهيد مع [وقت العمل الحرج].
لا يؤدي الرجوع إلى إصدار gunicorn إلى 19.6.0 إلى حل المشكلة.
قمنا بتحديث نواة المضيف إلى 4.9.0 (كان مجدولاً) ، وتمهيد العمال بنجاح دون أخطاء.
ولكن:

  • نستخدم 4 عمال
  • بعد 4 مكالمات بالضبط إلى تطبيق Django ، تنتهي مهلة المكالمات التالية ، وتظهر [CRITICAL WORKER TIMEOUT] في السجلات
  • يعرض أمر linux top 4 عمليات gunicorn عالقة مع استهلاك مرتفع جدًا لوحدة المعالجة المركزية.

سنقوم بتجربة gunicorn gevent لمعرفة ما إذا كنا قادرين على إعادة تطبيقنا عبر الإنترنت.

استخدام gunicorn مع gevent لم يصلح الخطأ.

أي تعديل حدث في هذه القضية ؟

يبدو أن neocolor تعرّف على خطأ حقيقي ضمن MSYS. قد تستحق قضية منفصلة.

bigunyak ما هي المنصة التي تعمل تحتها؟ لقد حاولت التكاثر باستخدام المثال البسيط ولا يمكنني القيام بذلك باتباع الخطوات الموضحة أعلاه بالضبط. هذا يتفق مع تجربتي في تشغيل تطبيقات متعددة في الإنتاج على أطر متعددة. لم يتغير نظام إخطار العامل مؤخرًا ، على حد علمي. النظام الأساسي الخاص بي هو Python 3.7 على MacOS 10.13.6 ، لكنني قمت بتشغيل Gunicorn في الإنتاج مع عمال المزامنة للعديد من التطبيقات على Python 2.7 و 3.6.5 ولا أرى سوى مهلات العمال عندما تكون هناك طلبات طويلة مشروعة تمنع العمال.

بالنسبة إلى Tberdy : ماذا يحدث إذا حاولت تعيين --worker-tmp-dir في مكان ما خارج نظام ملفات tmpfs؟ أنا فقط أتساءل عما إذا كان من الممكن أن تتداخل جبال الألب أو عامل الرصيف أو المجموعة بطريقة ما مع كيفية إخطار العمال للحكم.

راجع أيضًا # 1388 لمشكلات tmpfs المتعلقة بـ Docker.

لدي هذه المشكلة ل.

لدي هذه المشكلة أيضًا ، كانت مزامنة gunicorn تعمل بشكل جيد حتى الأمس ، وبدأت في إعداد التقارير ، يبدو أن مهلة العمال [الحرجة] باستخدام gevent يحل مشكلتي ، لكنني أريد حقًا معرفة سبب حدوث ذلك.

@ timoj58cjmash هل يمكنك تقديم المزيد من التفاصيل حول المشكلة؟ كيف تقوم بتشغيل برنامج gunicorn (في vm ؟، options ...) ، أي نظام ملفات ، OS؟ أي شيء يمكن أن يساعد في التكاثر سيكون مفيدًا جدًا :)

benoitc أنا أقوم بتشغيل برنامج gunicorn لبدء مشروع Django الخاص بي على kubernetes ، فإن وسيطاتي في gunicorn هي --bind = $ port --workers = 7 - timeout = 1200 --log-level = debug --access-logfile - error-logfile - "

الأخطاء التي أحصل عليها من السجلات

"" E [2018-08-09 21:47:56 +0000] [13] [INFO] تمهيد العامل باستخدام pid: 13

E [2018-08-09 21:47:56 +0000] [14] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 14

E [2018-08-09 21:47:56 +0000] [12] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 12

هـ [2018-08-09 21:47:56 +0000] [1] [DEBUG] 7 عمال

E [2018-08-09 21:47:56 +0000] [11] [INFO] تمهيد العامل مع pid: 11

E [2018-08-09 21:47:55 +0000] [10] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 10

E [2018-08-09 21:47:55 +0000] [9] [INFO] تمهيد العامل باستخدام معرف المنتج: 9

E [2018-08-09 21:47:55 +0000] [8] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 8

E [2018-08-09 21:47:55 +0000] [1] [INFO] استخدام العامل: المزامنة

E [2018-08-09 21:47:55 +0000] [1] [INFO] الاستماع على: http://0.0.0.0 : 4040 (1)

E [2018-08-09 21:47:55 +0000] [1] [DEBUG] تمهيد الحكم

E [2018-08-09 21:47:55 +0000] [1] [INFO] بدء تشغيل Gunicorn 19.7.1

E raw_paste_global_conf: []

الأصفار الإلكترونية: TLSv1

E do_handshake_on_connect: خطأ

E suppress_ragged_eofs: صحيح

يحذر من: لا شيء

E cert_reqs: 0

E ssl_version: 2

E certfile: لا شيء

E keyfile: لا شيء

E proxy_allow_ips: ['127.0.0.1']

E proxy_protocol: خطأ

E on_exit:

تغيير العمال:

E worker_exit:

خروج الطفل:

البريد_الطلب:

الطلب المسبق:

E pre_exec:

E worker_abort:

E worker_int:

E post_worker_init:

البريد الإلكتروني:

E pre_fork:

ه عندما_ جاهز:

E on_reload:

هـ عند البدء:

لصق E: لا شيء

E pythonpath: لا شيء

E default_proc_name: art.wsgi

E proc_name: لا شيء

E statsd_prefix:

E statsd_host: لا يوجد

E enable_stdio_inheritance: خطأ

E syslog_facility: المستخدم

E syslog_prefix: لا شيء

E syslog: خطأ

E syslog_addr: udp: // localhost : 514

E logconfig: لا شيء

E logger_class: gunicorn.glogging.Logger

E capture_output: خطأ

E loglevel: التصحيح

E errorlog: -

E access_log_format:٪ (h) s٪ (l) s٪ (u) s٪ (t) s "٪ (r) s"٪ (s) s٪ (b) s "٪ (f) s" "٪ ( كما"

الوصول الإلكتروني: -

E forwarded_allow_ips: ['127.0.0.1']

E secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl'، 'X-FORWARDED-PROTO': 'https'، 'X-FORWARDED-SSL': 'on'}

E tmp_upload_dir: لا شيء

E initgroups: خطأ

E umask: 0

المجموعة E: 0

المستخدم الإلكتروني: 0

E worker_tmp_dir: لا شيء

E pidfile: لا شيء

E raw_env: []

E daemon: خطأ

E chdir: / usr / src / app

E sendfile: لا شيء

E preload_app: خطأ

E check_config: خطأ

E spew: خطأ

E reload_engine: تلقائي

إعادة تحميل البريد: خطأ

E limit_request_field_size: 8190

E limit_request_fields: 100

E limit_request_line: 4094

ه البقاء على قيد الحياة: 2

E graceful_timeout: 30

المهلة الإلكترونية: 1200

E max_requests_jitter: 0

الحد الأقصى للطلبات: 0

عدد توصيلة العاملين الإلكترونيين: 1000

خيوط E: 1

E worker_class: sync

عمال البريد الإلكتروني: 7

الأعمال المتراكمة: 2048

ربط E: ['0.0.0.0:4040']

التكوين E: لا شيء

E [2018-08-09 21:47:55 +0000] [1] [DEBUG] التكوين الحالي:

أنا لا الهجرات لتطبيق.

أقوم بتشغيل عمليات الترحيل:

أقوم بتطبيق جميع عمليات الترحيل: admin ، auth ، contenttypes ، core ، dashboard ، jet ، oauth2_provider ، Session

أنا عمليات لأداء:

E [2018-08-09 21:47:20 +0000] [13] [INFO] خروج العامل (pid: 13)

E os.path.dirname (os.path.dirname (__ file__)) ، ".env"))

E /usr/src/app/art/wsgi.py:19: تحذير المستخدم: لا يقرأ /usr/src/app/.env - إنه غير موجود.

E [2018-08-09 21:47:00 +0000] [21] [INFO] تمهيد العامل مع رقم التعريف الشخصي: 21

E [2018-08-09 21:47:00 +0000] [1] [INFO] التعامل مع الإشارة: المدى

E [2018-08-09 21:46:35 +0000] [12] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 12

E [2018-08-09 21:46:34 +0000] [13] [INFO] تمهيد العامل باستخدام رقم التعريف الشخصي: 13

E [2018-08-09 21:46:34 +0000] [11] [INFO] تمهيد العامل باستخدام معرف المنتج: 11

هـ [2018-08-09 21:46:34 +0000] [1] [DEBUG] 7 عمال

E [2018-08-09 21:46:34 +0000] [10] [INFO] تمهيد العامل مع pid: 10

E [2018-08-09 21:46:34 +0000] [9] [INFO] تمهيد العامل باستخدام معرف المنتج: 9

E [2018-08-09 21:46:34 +0000] [8] [INFO] تمهيد العامل مع pid: 8

E [2018-08-09 21:46:34 +0000] [7] [INFO] تمهيد العامل باستخدام معرف المنتج: 7

E [2018-08-09 21:46:34 +0000] [1] [INFO] استخدام العامل: المزامنة

E [2018-08-09 21:46:34 +0000] [1] [INFO] الاستماع على: http://0.0.0.0 : 4040 (1)

E [2018-08-09 21:46:34 +0000] [1] [DEBUG] تمهيد الحكم

E [2018-08-09 21:46:34 +0000] [1] [INFO] بدء تشغيل gunicorn 19.7.1

E raw_paste_global_conf: []

الأصفار الإلكترونية: TLSv1

E do_handshake_on_connect: خطأ

E suppress_ragged_eofs: صحيح

يحذر من: لا شيء

E cert_reqs: 0

E ssl_version: 2

E certfile: لا شيء

E keyfile: لا شيء

E proxy_allow_ips: ['127.0.0.1']

E proxy_protocol: خطأ

E on_exit:

تغيير العمال:

E worker_exit:

خروج الطفل:

البريد_الطلب:

الطلب المسبق:

E pre_exec:

E worker_abort:

E worker_int:

E post_worker_init:

البريد الإلكتروني:

E pre_fork:

ه عندما_ جاهز:

E on_reload:

هـ عند البدء:

لصق E: لا شيء

E pythonpath: لا شيء

E default_proc_name: art.wsgi

E proc_name: لا شيء

E statsd_prefix:

E statsd_host: لا يوجد

E enable_stdio_inheritance: خطأ

E syslog_facility: المستخدم

E syslog_prefix: لا شيء

E syslog: خطأ

E syslog_addr: udp: // localhost : 514

E logconfig: لا شيء

E logger_class: gunicorn.glogging.Logger

E capture_output: خطأ

E loglevel: التصحيح

E errorlog: -

E access_log_format:٪ (h) s٪ (l) s٪ (u) s٪ (t) s "٪ (r) s"٪ (s) s٪ (b) s "٪ (f) s" "٪ ( كما"

الوصول الإلكتروني: -

E forwarded_allow_ips: ['127.0.0.1']

E secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl'، 'X-FORWARDED-PROTO': 'https'، 'X-FORWARDED-SSL': 'on'}

E tmp_upload_dir: لا شيء

E initgroups: خطأ

E umask: 0

المجموعة E: 0

المستخدم الإلكتروني: 0

E worker_tmp_dir: لا شيء

E pidfile: لا شيء

E raw_env: []

E daemon: خطأ

E chdir: / usr / src / app

E sendfile: لا شيء

E preload_app: خطأ

E check_config: خطأ

E spew: خطأ

E reload_engine: تلقائي

إعادة تحميل البريد: خطأ

E limit_request_field_size: 8190

E limit_request_fields: 100

E limit_request_line: 4094

ه البقاء على قيد الحياة: 2

E graceful_timeout: 30

المهلة الإلكترونية: 1200

E max_requests_jitter: 0

الحد الأقصى للطلبات: 0

عدد توصيلة العاملين الإلكترونيين: 1000

خيوط E: 1

E worker_class: sync

عمال البريد الإلكتروني: 7

الأعمال المتراكمة: 2048

ربط E: ['0.0.0.0:4040']

التكوين E: لا شيء

E [2018-08-09 21:46:34 +0000] [1] [DEBUG] التكوين الحالي:

""

لقد كافحت قليلاً لإعادة إنتاج المشكلة هذه المرة لكنها لا تزال موجودة في أحدث إصدار من gunicorn 19.9.0.
خطوات إعادة إنتاجها هي نفسها تمامًا كما وصفتها في هذا المنشور .
نظامي هو Arch Linux x86_64 GNU / Linux (kernel 4.17.2-1-ARCH) ، Python 3.6.5
هنا تتبع سجل جديد.

~$ gunicorn -b 0.0.0.0:5000 --log-level=debug hello
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] Current configuration:
  config: None
  bind: ['0.0.0.0:5000']
  backlog: 2048
  workers: 1
  worker_class: sync
  threads: 1
  worker_connections: 1000
  max_requests: 0
  max_requests_jitter: 0
  timeout: 30
  graceful_timeout: 30
  keepalive: 2
  limit_request_line: 4094
  limit_request_fields: 100
  limit_request_field_size: 8190
  reload: False
  reload_engine: auto
  reload_extra_files: []
  spew: False
  check_config: False
  preload_app: False
  sendfile: None
  reuse_port: False
  chdir: /home/dima/lerning/python/modules/gunicorn
  daemon: False
  raw_env: []
  pidfile: None
  worker_tmp_dir: None
  user: 1000
  group: 985
  umask: 0
  initgroups: False
  tmp_upload_dir: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  forwarded_allow_ips: ['127.0.0.1']
  accesslog: None
  disable_redirect_access_to_syslog: False
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  errorlog: -
  loglevel: debug
  capture_output: False
  logger_class: gunicorn.glogging.Logger
  logconfig: None
  logconfig_dict: {}
  syslog_addr: udp://localhost:514
  syslog: False
  syslog_prefix: None
  syslog_facility: user
  enable_stdio_inheritance: False
  statsd_host: None
  statsd_prefix: 
  proc_name: None
  default_proc_name: hello
  pythonpath: None
  paste: None
  on_starting: <function OnStarting.on_starting at 0x7f5f8b9dad08>
  on_reload: <function OnReload.on_reload at 0x7f5f8b9dae18>
  when_ready: <function WhenReady.when_ready at 0x7f5f8b9daf28>
  pre_fork: <function Prefork.pre_fork at 0x7f5f8b4ec0d0>
  post_fork: <function Postfork.post_fork at 0x7f5f8b4ec1e0>
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f5f8b4ec2f0>
  worker_int: <function WorkerInt.worker_int at 0x7f5f8b4ec400>
  worker_abort: <function WorkerAbort.worker_abort at 0x7f5f8b4ec510>
  pre_exec: <function PreExec.pre_exec at 0x7f5f8b4ec620>
  pre_request: <function PreRequest.pre_request at 0x7f5f8b4ec730>
  post_request: <function PostRequest.post_request at 0x7f5f8b4ec7b8>
  child_exit: <function ChildExit.child_exit at 0x7f5f8b4ec8c8>
  worker_exit: <function WorkerExit.worker_exit at 0x7f5f8b4ec9d8>
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f5f8b4ecae8>
  on_exit: <function OnExit.on_exit at 0x7f5f8b4ecbf8>
  proxy_protocol: False
  proxy_allow_ips: ['127.0.0.1']
  keyfile: None
  certfile: None
  ssl_version: 2
  cert_reqs: 0
  ca_certs: None
  suppress_ragged_eofs: True
  do_handshake_on_connect: False
  ciphers: TLSv1
  raw_paste_global_conf: []
[2018-08-10 09:48:40 +0200] [23114] [INFO] Starting gunicorn 19.9.0
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] Arbiter booted
[2018-08-10 09:48:40 +0200] [23114] [INFO] Listening at: http://0.0.0.0:5000 (23114)
[2018-08-10 09:48:40 +0200] [23114] [INFO] Using worker: sync
[2018-08-10 09:48:40 +0200] [23117] [INFO] Booting worker with pid: 23117
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] 1 workers
[2018-08-10 09:48:45 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:48:54 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:00 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:18 +0200] [23117] [DEBUG] Closing connection. 
[2018-08-10 09:49:18 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:23 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:37 +0200] [23117] [DEBUG] Closing connection. 
[2018-08-10 09:49:37 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:50 +0200] [23117] [DEBUG] Closing connection. 
[2018-08-10 09:51:11 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:51:13 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:51:43 +0200] [23114] [CRITICAL] WORKER TIMEOUT (pid:23117)
[2018-08-10 09:51:43 +0200] [23117] [INFO] Worker exiting (pid: 23117)
[2018-08-10 09:51:44 +0200] [23229] [INFO] Booting worker with pid: 23229

كما كان من قبل لاختباره ، كنت أصاب http://0.0.0.0 : 5000 / في Chromium.
يوجد أدناه محتوى Pipfile و Pipfile.lock لتتمكن من رؤية البيئة الدقيقة.

  • ملف
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
flask = "*"
gunicorn = "*"

[dev-packages]

[requires]
python_version = "3.6"
  • Pipfile.lock
{
    "_meta": {
        "hash": {
            "sha256": "81cb5d5f0b11719d8d9c5ec9cc683fdcf959c652fda256d5552a82d0f459a99c"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.6"
        },
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {
        "click": {
            "hashes": [
                "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
                "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
            ],
            "version": "==6.7"
        },
        "flask": {
            "hashes": [
                "sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
                "sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
            ],
            "index": "pypi",
            "version": "==1.0.2"
        },
        "gunicorn": {
            "hashes": [
                "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471",
                "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"
            ],
            "index": "pypi",
            "version": "==19.9.0"
        },
        "itsdangerous": {
            "hashes": [
                "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519"
            ],
            "version": "==0.24"
        },
        "jinja2": {
            "hashes": [
                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
            ],
            "version": "==2.10"
        },
        "markupsafe": {
            "hashes": [
                "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
            ],
            "version": "==1.0"
        },
        "werkzeug": {
            "hashes": [
                "sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
                "sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
            ],
            "version": "==0.14.1"
        }
    },
    "develop": {}
}

فقط لمعلوماتك ، أرى أيضًا هذا الفشل بشكل منتظم جدًا مع:

nohup gunicorn -w 8 - ملف سجل الوصول = - - ربط 127.0.0.1:5000 wsgi &

لدي فقط ملف wsgi.py

from chart_api import application
if __name__ == "__main__":
    application.run()

اسمحوا لي أن أعرف إذا كان هناك أي شيء تريد مني تجربته / تجربته أو إذا كانت هناك تفاصيل في السجلات تريد مني التحقق منها. أنا أشغل قارورة على GCP VM.

آسف على الرد المتأخر. أنا أديرها كـ

gunicorn --log-file = / home / ubuntu / log / gunicorn.log توقع بواجهة برمجة تطبيقات: app -b localhost: 5000 &

لقد استخدمت الإعداد gevent وما إلى ذلك ، لكنني قمت بتغيير تصميمي لما طلبت ذلك من أجل حل المشكلة ، ومن هنا جاء الإعداد الأساسي أعلاه (والذي فشل أيضًا ولكن هذا متوقع نظرًا لعدم وجود أي شيء)

الإصدار 3.6 من Python
env: aws tensorflow_p36 optmized (ubuntu)
nginx يجلس أمام gunicorn ، الذي ينفّذ تطبيق flask.

الإصدار 1.0.2
الإصدار 1.10.3 من nginx
إصدار gunicorn 19.9.0

لقد قمت بتغيير مهلات nginx أيضًا إذا كان هذا قد تسبب في ذلك.

تواجه نفس المشكلة مع خادم gunicorn

# gunicorn Applicat ionServer: app -b 0.0.0.0:6001 -w 8 --threads 4 --backlog 2048 \
# - timeout 120 --graceful-timeout 60 - سجلات ملف سجل الوصول / access.log \

- سجلات ملف سجل الخطأ / error.log --log-level = info

قارورة == 0.12.1
جونيكورن == 19.7.1

عند بدء تشغيل الخادم بالأمر أعلاه ، تم تجميد نظامي لبعض الوقت واستمرت pids العامل في التمهيد ، على الرغم من أنني أبقيت مهلة 120 ثانية ، ولا يقبل الخادم طلبًا واحدًا.

أي تعديل حدث في هذه القضية ؟ لدي نفس المشكلة

المهلة الزمنية [الحرجة] العامل

هل تتساءل عما إذا كان أي شخص قد أعاد إنتاج هذا بنجاح في صورة Docker؟

ترى هذا أيضًا عند محاولة تنفيذ عامل تشغيل ddtrace الخاص بـ datadog على تطبيق موجود بدءًا من gunicorn -k gevent --threads 4.

أثر مضحك لمخرج SystemExit لم أره من قبل أيضًا ...
[2018-11-07 11:11:50 +0000] [15987] [INFO] Booting worker with pid: 15987 [2018-11-07 11:11:50 +0000] [15977] [DEBUG] 1 workers [2018-11-07 11:12:20 +0000] [15977] [CRITICAL] WORKER TIMEOUT (pid:15987) Exception SystemExit: 1 in <bound method LibevLoop._loop_will_run of <cassandra.io.libevreactor.LibevLoop object at 0x7f3cb66d4a50>> ignored

أنا قادر على حل هذه المشكلة عن طريق مطابقة عدد العمال وعدد الخيوط.

لقد قمت بتعيين workers = (2 * cpu_count) + 1 ولم أقم بتعيين المواضيع.

بمجرد أن قمت بتغيير threads = workers ، بدأ كل شيء يعمل بشكل جيد. فقط في حالة ، إذا كان هذا يساعد شخص ما.

هكذا تبدو الآن

def run(host='0.0.0.0', port=8080, workers=1 + (multiprocessing.cpu_count() * 2)):
    """Run the app with Gunicorn."""

    if app.debug:
        app.run(host, int(port), use_reloader=False)
    else:
        gunicorn = WSGIApplication()
        gunicorn.load_wsgiapp = lambda: app
        gunicorn.cfg.set('bind', '%s:%s' % (host, port))
        gunicorn.cfg.set('workers', workers)
        gunicorn.cfg.set('threads', workers)
        gunicorn.cfg.set('pidfile', None)
        gunicorn.cfg.set('worker_class', 'sync')
        gunicorn.cfg.set('keepalive', 10)
        gunicorn.cfg.set('accesslog', '-')
        gunicorn.cfg.set('errorlog', '-')
        gunicorn.cfg.set('reload', True)
        gunicorn.chdir()
        gunicorn.run()

واجهت هذه المشكلة أثناء تشغيل Django بحاوية Docker واحدة على AWS Elastic Beanstalk. لقد قمت بحل المشكلة عن طريق إصلاح مجموعات الأمان الخاصة بي للتأكد من أن مثيل EC2 الخاص بي يمكنه التحدث إلى مثيل RDS الخاص بي. أدرك أن هذا قد لا يكون الحل لـ 99٪ من الأشخاص بشأن هذه المشكلة ، لكني أترك هذه الملاحظة لمساعدة الآخرين على تجنب إضاعة ساعات في السقوط في حفرة الأرانب هذه.

في حالتي ، تم حل المشكلة عن طريق تنفيذ systemctl daemon-reload .
قصة قصيرة طويلة كنت أعرف المهلة الافتراضية عند 30 ثانية ، لكنني لم أتمكن من تغييرها حتى أدركت أنه كان علي بالطبع إعادة تحميل البرنامج الخفي systemd لتطبيق التغييرات على الخدمة.

bigunyakbenoitctilgovi
بعد مطاردة طويلة من google goose وبعض التجارب ، أعتقد أن السبب الجذري لهذه المشكلة هو chrome "خدمة الاتصال المسبق / التنبؤ" (والتي يتم تمكينها افتراضيًا في كل من Chrome و Chromium).

jeiting قام بكتابة لطيفة عن هذه المسألة
https://hackernoon.com/chrome-preconnect-breaks-singly-threaded-servers-95944be16400
بعض القراءات الإضافية:
https://github.com/corydolphin/flask-cors/issues/147
https://github.com/pallets/flask/issues/2169

TLDR
في بعض الحالات ، يفتح Chrome / Chromium ويحمل اتصال (اتصالات) TCP "فارغ" (أي أنه يتوقع أن يجلب موردًا آخر قريبًا). إذا وصل اتصال (اتصالات) TCP "الفارغ" إلى خادم gunicorn الخاص بك أولاً ، فيمكن أن يعلق أي طلب "حقيقي" لاحق من chrome خلف الطلب "الفارغ" حتى تنتهي مهلة معالجة العامل (العمال) للطلب "الفارغ". من المرجح أن يحدث هذا إذا كنت تقوم بتشغيل عامل مزامنة واحد فقط في gunicorn. ولكن كما وجدت تجاربي ، يمكن أن يحدث ذلك حتى إذا كنت تقوم بتشغيل عدة عمال مزامنة.

بيئتي

  • نظام التشغيل الأصلي الخاص بي هو Ubuntu 17
  • لديّ واجهة برمجة تطبيقات أخرى تعمل في حاوية عامل إرساء محلي. الأسطر ذات الصلة من Dockefile
FROM ubuntu:18.04
...
RUN pip3 install Flask==1.0.2
RUN pip3 install gunicorn==19.9.0
RUN pip3 install flask-cors==3.0.6
......
  • لدي 3 متصفحات مثبتة: Firefox 61.0.1 و Chromium 67.0.3396.99 و Chrome 70.0.3538.102
  • لدي تطبيق تفاعلي يتم تقديمه من حاوية عامل إرساء مختلفة على منفذ مختلف
  • يجعل تطبيق رد الفعل طلبات CORS AJAX إلى واجهة برمجة التطبيقات (API) الخاصة بي (إنها طلبات CORS لأن جافا سكريبت يتم تقديمه على منفذ مضيف محلي أثناء إرسال مكالمات واجهة برمجة التطبيقات إلى منفذ مضيف محلي آخر)
  • الطلب الذي يتم "حظره" دائمًا في تجاربي هو طلب CORS OPTIONS (يتم تشغيله بواسطة المتصفح لطلب الإذن لتنفيذ طلب POST بعد ذلك). يبدو منطقيًا أن المستعرض سيحاول إجراء اتصالات تنبؤية مع مكالمة OPTIONS لأنه من المحتمل أن يتابع مع مكالمة POST.

التجربة 1
تكوين Gunicorn: عامل مزامنة واحد (المهلة الافتراضية 30 ثانية)

Firefox: في كل تحميل لصفحة تفاعل تقريبًا ، يتم حظر طلب CORS OPTIONS لمدة 5 ثوانٍ ، ثم ينجح.
Chromium: عند كل تحميل لصفحة تفاعل ، يتم حظر طلب CORS OPTIONS لمدة 1.5 دقيقة !!!! ثم ينجح.
Chromium (خدمة التنبؤ معطلة): يتم تحميل كل شيء بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد

التجربة 2
تكوين Gunicorn: 4 عمال مزامنة (المهلة الافتراضية 30 ثانية)

Firefox: يتم تحميل كل شيء بشكل جيد
Chromium: في كل تحميل لصفحة تفاعل ثالث ، يتم حظر طلب CORS OPTIONS لمدة 30 ثانية ثم ينجح.
Chromium (خدمة التنبؤ معطلة): يتم تحميل كل شيء بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد

التجربة 3
تكوين Gunicorn: 8 عمال مزامنة (المهلة الافتراضية 30 ثانية)

Firefox: يتم تحميل كل شيء بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد

التجربة 4
تشغيل flask dev server بـ threaded=True

Firefox: يتم تحميل كل شيء بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد
الكروم: كل شيء يتم تحميله بشكل جيد

ملخص التجربة

  • يبدو أن Firefox يحتوي أيضًا على خدمة تنبؤ ، لكنها تبدو أكثر رشيقة. (التجربة 1)
  • يبدو أن Chromium هو الأكثر عدوانية في إنشاء اتصالات "التنبؤ". يبدو أنه يتم تشغيل ما يصل إلى 3-4 اتصالات "توقع" أثناء طلب OPTIONS (التجربة 1 و 2)
  • من المثير للدهشة أنه على الرغم من تمكين خدمة التنبؤ في Chrome أيضًا ، إلا أنه لم يتسبب في أي مشكلات في أي من التجارب (ربما يختلف ترتيب أو عدد اتصالات "التوقع" عن Chromium)

المحلول
في الإنتاج: أسهل حل هو وضع nginx أمام gunicorn. إذا كنت تريد أن تفهم سبب حل nginx لهذه المشكلة ، فإليك مقالة لطيفة تشرحها: https://www.brianstorti.com/the-role-of-a-reverse-proxy-to-protect-your-application-against -عملاء بطيئون /

في dev: أسهل إصلاح هو تشغيل flask dev server بـ threaded=True . أو يمكنك تعطيل خدمة التنبؤ في Chrome / Chromium.

تحسينات تصحيح أخطاء gunicorn
للمساعدة في تصحيح مشكلة مثل هذه في المستقبل ، أعتقد أنه من الجيد إضافة عبارات سجل تصحيح الأخطاء بجوار مكالمات select() و accept() في عامل المزامنة.
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L26
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L34
سيُظهر هذا أن العامل قد قبل اتصال TCP جديد ، لكنه لا يتلقى أي بيانات.

asnisarenko سوبر الكتابة المتابعة ، شكرا. # 1929 هي حالة أخرى غير عادية للعميل البطيء الذي ينتج عنه أعراض مماثلة في الخادم أحادي الخيط - في هذه الحالة ، تبدو مصافحة TLS لمنفذ غير TLS كعميل بطيء الكتابة ، لأنه يفشل في إرسال رؤوس معقولة بسرعة .

قد يكون Gunicorn ، بالنسبة لعمال المزامنة أحادية الخيط ، سيحتاجون إلى بعض الضبط الجديد ، وهو إسقاط عميل قوي للعملاء الذين يفشلون في إرسال أول سطر طلب على الأقل ، إن لم يكن جميع الرؤوس ، في غضون فترة زمنية معقولة.

إذا حدث هذا في تطبيقك ، يمكنك إضافة بعض رموز التشخيص المؤقتة:

def trace_on_abort():
    import signal
    import traceback

    def print_trace(sig, frame):
        print(''.join(traceback.format_stack(frame)))

    signal.signal(signal.SIGABRT, print_trace)

نأمل أن يكشف هذا عن مكان توقف تطبيقك.

على سبيل المثال ، تمكنت بطريقة ما من الوصول إلى import flask قبل gevent.monkey.patch_all() وهكذا انتهى الأمر بـ Flask الخاص بي app._before_request_lock إلى أن يكون قفلًا غير gevent (على سبيل المثال ، عادي غير مصحح threading.Lock ). في مثل هذه الحالة ، قد يتسبب طلبان متعاقبان عند بدء تشغيل التطبيق في تعليقه (الطلب الثاني سيقفل سلسلة المحادثات بالكامل). لكن هذا كان خطأي ، وقد يختلف الخطأ الخاص بك.

asnisarenko لست متأكدًا من سبب read() s من المقبس ، فسوف يحظر greenlet ، ولكن نظرًا لأن read يجب أن يكون مصححًا بالقردة ، فإنه سينتج عنه الخضر الأخرى.

تضمين التغريدة
تتحدث هذه المشكلة عن تشغيل gunicorn مع التكوين الافتراضي. فئة العامل الافتراضية هي sync http://docs.gunicorn.org/en/stable/settings.html#worker -class

يستخدم العاملون sync نموذج ما قبل الانقسام ويقوم كل عامل بمعالجة طلب / اتصال TCP واحد في كل مرة.

لا أعرف سبب ذلك بالنسبة لي ، ولكن التبديل من نوع العامل الافتراضي sync إلى eventlet حل المشكلة:

CMD pipenv run gunicorn webapp -b 0.0.0.0:8080 -k eventlet

حظا طيبا وفقك الله.

ربما سيساعدني هذا فقط ، ولكن نظرًا لأنني استغرقت 7 ساعات لتصحيح هذه المشكلة من جانبي (تطبيق Flask / Gunicorn يعمل في Docker على EC2) ، إذا كان بإمكاني تجنب هذا الصداع لعدد قليل من الأشخاص ، فهذا انتصار صغير.

حد ذاكرة الحاوية كان منخفضًا جدًا.

إذا حدث تسرب للذاكرة في المستقبل ، فسأحاول وضع حد أعلى للذاكرة ، لكن في الوقت الحالي ، لن يكون هناك حد كافٍ.

شكرا

def trace_on_abort():
    import signal
    import traceback

    def print_trace(sig, frame):
        print(''.join(traceback.format_stack(frame)))

    signal.signal(signal.SIGABRT, print_trace)

أنت تساعدني كثيرا. EHU)))

أين تذهب هذه الطريقة trace_on_abort() ؟ في ملف كود التطبيق؟ هل تحتاج إلى تعليق توضيحي؟

@ mattg-vbt أضف هذا إلى بداية تطبيقك عندما تحتاج إلى التصحيح ، وقم بإزالته بمجرد الانتهاء من التصحيح

ikonst لقد أضفت هذا إلى تطبيقي ، لكنني لا أرى أنه يتعرض للضرب. أحصل على مهلة العامل ، لكن هذه الطريقة لم تنجح.

@ mattg-vbt هل يمكنك تجربة عمل kill -ABRT $pid لترى استدعاء الوظيفة print_trace ؟ (الفكرة هي أنك ستحصل على SIGABRT من werkzeug عندما تنتهي مهلة العامل لديك ، لكن دعنا أولاً نتحقق من استدعائها على الإطلاق)

asnisarenko للأقل ذكاء بيننا كيف يمكنني بعد ذلك تحديث ملف procfile؟

web gunicorn app:app -k gevent --worker-connections 1000 ؟

تضمين التغريدة
إذا كنت تستخدم موظفين gevent أنت (بدلاً من عمال المزامنة) ، فلا يجب أن تواجه هذه المشكلة. لذا فإن الأمر الذي نشرته يبدو جيدًا.

لا أتلقى هذه المشكلة مع العاملين gevent إلا عند التهيئة ، وهو أمر مزعج بعض الشيء لأنني أقوم بمعالجة بعض المهام قبل تشغيل تطبيقي. لكنني أقوم بتعيين مهلة عالية في الوقت الحالي.
لقد قمت بنشر ريبو اختبار قابل للتكرار هنا: https://github.com/zamponotiropita/test-gunicorn-worker-timeout -> فشل test_0 ، وتم اجتياز test_1 و test_2

zamponotiropita هل تحاول القيام بذلك لكل عامل أو لكل تطبيق قبل التفرع؟

ikonst يرجى التحقق من ملف التشغيل run.sh ، إنه لكل عامل. لم تظهر المشكلة في التحميل المسبق ، ولكن كان لدي مشكلات في الاتصال بقاعدة البيانات عند التحميل المسبق ، حيث يتم نسخ كائن التطبيق (ومعه اتصال قاعدة البيانات) واجتياز العمليات عند التفرع -> تعذر على قاعدة البيانات الخاصة بي التعامل اتصالات متطابقة بين السيد والعاملين ، ولم أتمكن من العثور على حل بديل

أواجه مشكلة مشابهة. أحاول إنشاء الكثير من البيانات أثناء التنقل باستخدام Flask
هذه الطريقة ، وتفشل بسبب انتهاء مهلة العامل بعد انتهاء صلاحية كل ما تم تعيينه في --timeout . مثال بسيط لإعادة الإنتاج:

test_gunicorn_timeout.py

import flask
from time import sleep


app = flask.Flask(__name__)


@app.route('/')
def gunicorn_timeout():
    def generator():
        for _ in range(10):
            yield b'Yet another line...'
            sleep(2)
    return flask.Response(generator(), mimetype='text/plain')

ثم قم بتشغيل gunicorn --timeout 10 test_gunicorn_timeout:app وعند طلب localhost:8000 بعد 10 ثوانٍ تحصل على ملف
[CRITICAL] WORKER TIMEOUT .

حاولت أيضًا الجري بـ -k gevent و -k eventlet ولم يتغير شيء.

أنا على نظام التشغيل windows 10 Pro. مع عامل إنشاء
gunicorn app -b 0.0.0.0:8000 -k gevent
عملت من أجلي عن طريق تثبيت gevent في حاوية python الخاصة بي
كيفية تثبيت برنامج gevent

ثم قم بتشغيل gunicorn --timeout 10 test_gunicorn_timeout:app وعند طلب localhost:8000 بعد 10 ثوانٍ تحصل على ملف
[CRITICAL] WORKER TIMEOUT .

حاولت أيضًا الجري بـ -k gevent و -k eventlet ولم يتغير شيء.

تضمين التغريدة

هل وجدت حلاً لمشكلة مهلة العامل [الحرجة]؟

لدي مشكلة مماثلة مع نقطة نهاية دفق القارورة التي أحاول نشرها على heroku (الذي يستخدم gunicorn). هناك ، من المفترض أن تحافظ الواجهة الأمامية للوكيل على الاتصال على قيد الحياة طالما يتم إرسال بعض البيانات في غضون 30 ثانية ، ولكن يبدو أن gunicorn يقتل العملية ببساطة إذا لم تنته في غضون 30 ثانية على الرغم من أنها لا تزال قيد التشغيل وتنتج البيانات.

وثائق البونيكورن ليست واضحة تمامًا بالنسبة لي في هذه النقطة. بالنسبة إلى - timeout ، تقول أن Workers silent for more than this many seconds are killed and restarted. لكن يبدو أن العمال يُقتلون بعد 30 ثانية على الرغم من أنهم ما زالوا ينتجون البيانات؟

وثائق البونيكورن ليست واضحة تمامًا بالنسبة لي في هذه النقطة. بالنسبة إلى - timeout ، يتم قتل العمال الصامتين لأكثر من هذه الثواني العديدة وإعادة تشغيلهم. لكن يبدو أن العمال يُقتلون بعد 30 ثانية على الرغم من أنهم ما زالوا ينتجون البيانات؟

@ kurt-hectic يجب تحسين التوثيق. نعني بالصمت الصمت من منظور عملية الحكم التي تتواصل مع العمال من خلال ملف مؤقت. إذا كان العامل مشغولاً بإرسال البيانات ، فلن يقوم بتحديث هذا الملف. من وجهة نظر الحكم ، العامل يفتقد دقات القلب.

أنظر أيضا # 1974.

باستخدام أي عامل بخلاف الافتراضي ، يجب على العامل المتزامن التخفيف من المشكلة مع تدفق الهيئات الكبيرة ، لأن العمال الآخرين سوف ينبضون بالملف المؤقت حتى عندما يتعاملون مع الطلبات.

@ kurt-hectic أعدت التحقق مرة أخرى من الخيار -k gevent وأدرجت sleep(0) بين تكرارات المولد وقد نجح الأمر بالفعل بالنسبة لي (لست متأكدًا من سبب عدم نجاحه في ذلك الوقت لقد نشرت السؤال رغم ذلك).

- المهلة = 5

هذا هو السبب الأكثر شيوعًا لهذه المشكلة.

آمل أن يساعدك الحل الخاص بي. قابلت مشكلة مهلة العامل الحرجة هذه منذ بضعة أيام وجربت بعض الحلول. يعمل الآن بشكل جيد.

إليك ما أفهمه وحلولي:

  1. حاول التحميل المسبق في gunicorn

يفشل في تشغيل العمال لأنه يحتاج إلى مزيد من الوقت لتحميل الحزمة ، مثل tensorflow backend ، لبدء الخدمة. لذلك عندما تواجه بطء وقت تشغيل التطبيق ، حاول تمكين خيار التحميل المسبق في gunicorn (راجع https://devcenter.heroku.com/articles/python-gunicorn#advanced-configuration).

مرحبا gunicorn

  1. حاول زيادة مهلة gunicorn

المهلة الافتراضية هي 30 ثانية. إذا كان التطبيق الخاص بك يحتاج حقًا إلى الكثير من الوقت لإنهاء واجهة برمجة التطبيقات ، فقم بزيادة المهلة.

مرحبا جونيكورن

ومع ذلك ، من وجهة نظري ، ليس من المنطقي أن تحتاج واجهة برمجة التطبيقات لأكثر من دقيقة واحدة للانتهاء. إذا كان الأمر كذلك ، فحاول إحراز بعض التقدم في التعليمات البرمجية الخاصة بك.

  1. إذا كنت تستخدم k8s ، فيمكنك أيضًا تعيين timeoutSeconds للحاوية / الصورة في yaml.

واجهت نفس المشكلة اليوم. في حالتي ، كانت واجهة برمجة التطبيقات تستغرق حوالي دقيقة لحساب البيانات والعودة إلى العميل ، مما أدى إلى حدوث أخطاء فادحة في مهلة العامل. لقد قمت بحلها عن طريق زيادة علامة timeout لـ gunicorn إلى أكثر من دقيقة - لقد نجحت ، ولم أتوقع عودة المشكلة. أتمنى أن يساعدك هذا. أنا أستخدم uvicorn.workers.UvicornWorker.

لقد أصلحت هذا عن طريق إضافة عمال إضافيين إلى gnuicorn:

web: gunicorn --workers=3 BlocAPI:app --log-file -

لا فكرة لماذا.

ربما كان لديك طريق مسدود؟ هل يقدم تطبيقك طلبات لنفسه؟

في الأحد ، 5 يناير 2020 ، 10:52 alpinechicken ، كتب [email protected] :

لقد أصلحت هذا عن طريق إضافة عمال إضافيين إلى gnuicorn:

الويب: gunicorn --workers = 3 BlocAPI: app --log-file -

لا فكرة لماذا.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/1801؟email_source=notifications&email_token=AAAEQJVQRCW3C63EZJWIN5DQ4G3WTA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMV99
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAAEQJXZM4NLK56DZMFSZALQ4G3WTANCNFSM4FDLD5PA
.

نعم ، هناك طريق يستدعي الآخر - هل هذا سيء؟

هذا يعني أنك بحاجة إلى عاملين على الأقل وإلا سيفعل الخادم الخاص بك
طريق مسدود. سينتظر الطلب حتى يستجيب الخادم للطلب الثاني
طلب (الذي سيتم وضعه في قائمة الانتظار).

تحصل على طلب واحد متزامن لكل عامل.

في الإثنين ، 6 يناير 2020 ، 02:45 alpinechicken ، كتب [email protected] :

نعم ، هناك طريق يستدعي الآخر - هل هذا سيء؟

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/1801؟email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMiss300
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA
.

آه هذا منطقي. شكرا!

في الثلاثاء ، 7 يناير 2020 ، الساعة 6:23 صباحًا ، كتب bobf [email protected] :

هذا يعني أنك بحاجة إلى عاملين على الأقل وإلا سيفعل الخادم الخاص بك
طريق مسدود. سينتظر الطلب حتى يستجيب الخادم للطلب الثاني
طلب (الذي سيتم وضعه في قائمة الانتظار).

تحصل على طلب واحد متزامن لكل عامل.

في الإثنين ، 6 يناير 2020 ، 02:45 alpinechicken ، كتب [email protected] :

نعم ، هناك طريق يستدعي الآخر - هل هذا سيء؟

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
<
https://github.com/benoitc/gunicorn/issues/1801؟email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMiss300
و
أو إلغاء الاشتراك
<
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA

.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/1801؟email_source=notifications&email_token=AAH2WRPVPVO2EJ53BKQW5B3Q4OHLRA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VM99
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAH2WRM2LLIB4O6OHCU5UG3Q4OHLRANCNFSM4FDLD5PA
.

worker_class '،' sync ')

أنا قادر على حل هذه المشكلة عن طريق مطابقة عدد العمال وعدد الخيوط.

لقد قمت بتعيين workers = (2 * cpu_count) + 1 ولم أقم بتعيين المواضيع.

بمجرد أن قمت بتغيير threads = workers ، بدأ كل شيء يعمل بشكل جيد. فقط في حالة ، إذا كان هذا يساعد شخص ما.

هكذا تبدو الآن

def run(host='0.0.0.0', port=8080, workers=1 + (multiprocessing.cpu_count() * 2)):
    """Run the app with Gunicorn."""

    if app.debug:
        app.run(host, int(port), use_reloader=False)
    else:
        gunicorn = WSGIApplication()
        gunicorn.load_wsgiapp = lambda: app
        gunicorn.cfg.set('bind', '%s:%s' % (host, port))
        gunicorn.cfg.set('workers', workers)
        gunicorn.cfg.set('threads', workers)
        gunicorn.cfg.set('pidfile', None)
        gunicorn.cfg.set('worker_class', 'sync')
        gunicorn.cfg.set('keepalive', 10)
        gunicorn.cfg.set('accesslog', '-')
        gunicorn.cfg.set('errorlog', '-')
        gunicorn.cfg.set('reload', True)
        gunicorn.chdir()
        gunicorn.run()

وفقًا لـ gunicorn doc ، فإنه يغير فئة العامل من المزامنة إلى gthread إذا تم ذكر أكثر من موضوع واحد.
ملاحظة:-
إذا حاولت استخدام نوع عامل المزامنة وقمت بتعيين إعداد سلاسل الرسائل على أكثر من 1 ، فسيتم استخدام نوع عامل gthread بدلاً من ذلك.

قضيتي:

البيئة: Ubuntu18.04 + gunicorn + nginx + flask

نقطة تثبيت gunicorn [gevent] في بيئتي الافتراضية

تغيير gunicorn -b localhost:8000 -w 4 web:app إلى gunicorn -b localhost:8000 -k gevent web:app

إنها تعمل.

شكراً لكل من فعل الكثير لمساعدة بعضهم البعض في حل مشكلاتهم. يرجى الاستمرار في النشر لهذه المشكلة إذا بدا ذلك مناسبًا.

ومع ذلك ، أقوم بإغلاق هذه المشكلة لأنني لا أعتقد أن هناك أي خطأ في Gunicorn هنا ولا أعتقد أن هناك أي إجراء يجب اتخاذه ، على الرغم من أنني سأساعد بسعادة في مراجعة العلاقات العامة التي تحاول إضافة وثائق لهذا بطريقة أو بأخرى أو تحسين رسائل السجل.

من فضلك لا تسيء فهم نيتي. إذا كنت تشك في وجود خطأ في Gunicorn وترغب في مواصلة المناقشة ، فيرجى القيام بذلك. على نحو مفضل ، افتح بطاقة جديدة مع تطبيق مثال يعيد إنتاج مشكلتك. ومع ذلك ، في هذه المرحلة ، هناك العديد من المشكلات والحلول والمحادثات المختلفة في هذه المشكلة بحيث لا يمكن قراءتها بشكل كبير.

إذا قمت بتشغيل Gunicorn بدون وكيل عكسي للتخزين المؤقت أمامه ، فستحصل على مهلات مع عامل المزامنة الافتراضي ، لأي عدد من الأسباب. الأشياء الشائعة هي:

  • عملاء بطيئين
  • التوصيل المسبق / الجلب المسبق للاتصالات التي تركتها المتصفحات والوكلاء مفتوحة
  • استجابات طويلة بسبب استدعاء واجهات برمجة التطبيقات الخارجية أو القيام بالكثير من العمل المرتبط بوحدة المعالجة المركزية

يمكنك التبديل إلى أنواع العمال غير المتزامنة أو المترابطة ، أو يمكنك وضع Gunicorn خلف وكيل عكسي للتخزين المؤقت. إذا كنت تعلم أن المهلات الخاصة بك ترجع إلى قيام التعليمات البرمجية الخاصة بك بإجراء مكالمات بطيئة لواجهات برمجة التطبيقات الخارجية أو القيام بعمل مهم تتوقعه ، فيمكنك زيادة الخيار --timeout .

هذا يعني أنك بحاجة إلى عاملين على الأقل وإلا فسوف يتعطل خادمك. سينتظر الطلب حتى يستجيب الخادم للطلب الثاني (الذي سيتم وضعه في قائمة الانتظار). تحصل على طلب واحد متزامن لكل عامل.
...
يوم الاثنين، 6 يناير 2020، 02:45 دجاج الدجاج، @ . * > كتب: نعم ، هناك طريق يدعو آخر - هل هذا سيء؟

هل هذا هو الحال عند استدعاء وظيفة "إعادة التوجيه" كقيمة العودة لمسار؟

هل هذا هو الحال عند استدعاء وظيفة "إعادة التوجيه" كقيمة العودة لمسار؟

لا. تستجيب عملية إعادة توجيه القارورة بإعادة توجيه HTTP ويكون العامل حينها حراً في قبول طلب جديد. يقدم العميل طلبًا آخر عندما يرى هذه الاستجابة وعندما يكون العامل جاهزًا سيتلقى هذا الطلب.

لقد أصلحت هذا عن طريق إضافة عمال إضافيين إلى gnuicorn:

web: gunicorn --workers=3 BlocAPI:app --log-file -

لا فكرة لماذا.

هل هذا متعلق بتعليق anilpai سابقًا حيث قام بتعيين workers=1 + (multiprocessing.cpu_count() * 2) ..؟

لدي مشكلة مماثلة لهذا. تبين أنه كان لدي خطأ في نقطة الدخول الخاصة بي إلى التطبيق. من تصحيح الأخطاء ، بدا أنني كنت أقوم أساسًا بتشغيل تطبيق flask من gunicorn ، الذي يدخل العاملون فيه لاحقًا في حلقة اتصال لا نهائية تنتهي كل 30 ثانية.

أنا متأكد من أن هذا لا يؤثر على جميع المستخدمين أعلاه ، ولكنه قد يؤثر على البعض.

في ملفي module/wsgi.py الذي أستخدمه gunicorn module.wsgi كان لدي -

application = my_create_app_function()
application.run(host="0.0.0.0")

بينما كان يجب علي -

application = my_create_app_function()
if __name__ == "__main__":
     application.run(host="0.0.0.0")

بشكل أساسي ، لا تريد الاتصال بـ application.run() عند استخدام gunicorn. لن يكون __name__ تحت gunicorn "__main__" ، لكنه سيكون في Flask ، لذلك لا يزال بإمكانك التصحيح محليًا.

لم أتمكن من العثور على إشارة إلى هذا في مستندات gunicorn ، لكن يمكنني أن أتخيل أنها حالة خطأ شائعة ، لذلك ربما يلزم بعض التحذير.

هذا لا يزال يحدث. أدت إضافة --preload إلى مكالمة Gunicorn إلى إصلاح المشكلة بالنسبة لي.

هل ما زال هذا الخطأ غير ثابت؟ أنا ألاحظ هذا السلوك بالضبط.

يبدأ Gunicorn هكذا في systemd:

[Service]
PIDFile = /run/gunicorn.pid
WorkingDirectory = /home/pi/pyTest
ExecStart=/usr/local/bin/gunicorn  app:app  -b 0.0.0.0:80 --pid /run/gunicorn.pid
RuntimeDirectory=/home/pi/pyTest
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
User=root
Group=root
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/gunicorn
PrivateTmp = true

تنتهي مهلة عملية العامل باستمرار وتتم إعادة التشغيل:

Jul 10 15:19:20 raspberryVM gunicorn[10941]: [2020-07-10 15:19:20 -0700] [10941] [CRITICAL] WORKER TIMEOUT (pid:10944)
Jul 10 15:19:20 raspberryVM gunicorn[10941]: [2020-07-10 15:19:20 -0700] [10944] [INFO] Worker exiting (pid: 10944)
Jul 10 15:20:15 raspberryVM gunicorn[10941]: [2020-07-10 15:20:15 -0700] [10985] [INFO] Booting worker with pid: 10985

app.py هو تطبيق Flask ثلاثي.

هل تم إغلاق هذه المشكلة باعتبارها لا تصلح؟

كنت أيضا أواجه نفس المشكلة

ولكن بعد تصحيح الأخطاء ، تمكنت من العثور على أنه أثناء بدء تشغيل تطبيق Django ، كان أحد التبعيات يستغرق وقتًا أطول من الوقت المتوقع ، (في حالتي اتصال DB خارجي) مما يجعل العامل gunicron ينتهي مهلة

عندما قمت بحل مشكلة الاتصال ، تم حل مشكلة المهلة أيضًا ...

هذه ليست حالتي. اختبرت باستخدام نوع التطبيق "Hello، World" ، بدون أي تبعيات. لذلك ما زلت في حيرة من هذا ، ولكن يبدو أنه من غير الممكن أن يكون لديك Gunicorn بخيط طويل. تتم إعادة تشغيل العملية العاملة وبالتالي تقضي على مؤشر الترابط الذي يعمل لفترة طويلة.

تضمين التغريدة
هذا على الأرجح ليس حشرة غونيكورن. انظر بلدي الثناء أعلاه في الموضوع. إنه أحد الآثار الجانبية لقيام المتصفحات بإرسال اتصالات TCP "متوقعة" فارغة وتشغيل برنامج gunicorn مع عدد قليل من عمال المزامنة دون حماية من اتصالات TCP الفارغة.

هل هناك بنية / تصميم مرجعي يوضح طريقة مناسبة لإعداد تطبيق Gunicorn flask باستخدام مؤشر ترابط عامل طويل (دائم)؟

إذا لم يكن هذا خطأ ، فإنه يبدو قطعة أثرية أو قيد على بنية / تصميم Gunicorn.

لماذا لا يعمل عامل المزامنة إلى الأبد ويقبل اتصالات العملاء. سيقوم هذا العامل بإغلاق المقبس حسب الحاجة ، ومع ذلك يستمر في التشغيل دون التنفيذ (ومن ثم يستمر تشغيل مؤشر ترابط العامل).

تضمين التغريدة
يجب أن تكون أكثر تحديدًا بشأن المشكلة التي تحاول حلها.

تحدث المشكلة التي تمت مناقشتها في هذا الموضوع في بيئة التطوير ، والحل الأسهل هو إما إضافة المزيد من عمال المزامنة أو استخدام عمال مترابطة.

إذا كنت ترغب في تجنب هذه المشكلة في إعداد الإنتاج ، يمكنك استخدام عمال gevent ، أو يمكنك وضع nginx أمام gunicorn.
تضع بعض PaaS بالفعل nginx أمام حاوية عامل الإرساء ، لذلك لا داعي للقلق بشأنه. مرة أخرى الحل يعتمد على السياق والتفاصيل.

هذه قراءة جيدة.
https://www.brianstorti.com/the-role-of-a-reverse-proxy-to-protect-your-application-against-slow-clients/

يمكنك التحقق من صفحة التصميم من الوثائق. عمال غير متزامن واحد
طريقة لتشغيل مهام طويلة.

يوم السبت 8 أغسطس 2020 الساعة 18:00 كتب leonbrag [email protected] :

هل توجد بنية / تصميم مرجعي يوضح طريقة مناسبة للإعداد
تطبيق Gunicorn flask مع مؤشر ترابط عامل طويل (دائم)؟

إذا لم يكن هذا خطأ ، فيبدو أنه قطعة أثرية أو قيد على
العمارة / التصميم في Gunicorn.

لماذا لا يعمل عامل المزامنة إلى الأبد ويقبل اتصالات العملاء. مثل
يقوم العامل بإغلاق المقبس حسب الحاجة ، ومع ذلك يستمر في العمل دون تنفيذ
(ومن ثم يستمر مؤشر ترابط العامل في التشغيل).

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-670944797 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAADRIWRQGIP3R5PMVJ5ENTR7VZA3ANCNFSM4FDLD5PA
.

>

مرسلة من هاتفي المحمول

الويب: gunicorn --workers = 3 التطبيق: التطبيق - مهلة 200 - ملف السجل -

لقد أصلحت مشكلتي عن طريق زيادة المهلة

راجع أيضًا # 1388 لمشكلات tmpfs المتعلقة بـ Docker.

أوه ، شكرًا جزيلاً راندال ، لقد نسيت إضافة --worker-tmp-dir /dev/shm إلى الحجج الجونيكورن عندما كنت أدير gunicorn في Docker.

راجع للشغل 64 ميغابايت ستكون كافية لذاكرة التخزين المؤقت gunicorn؟

تطبيق gunicorn
أو
التطبيق gunicorn

عملت لي ... أفضل مهلة واحدة.

غريب ، لقد أضفت --worker-tmp-dir /dev/shm لكني ما زلت أتلقى:

[2020-11-27 21:01:42 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)

للتأكد من أن /dev/shm هو ramfs الذي قمت بقياسه:

image

المعلمات هي التالية:

    command: /bin/bash -c "cd /code/ && pipenv run gunicorn --worker-tmp-dir /dev/shm conf.wsgi:application --bind 0.0.0.0:8022 --workers 5 --worker-connections=1000"

ملاحظة: أنا أستخدم PyPy

attajutt timeout أمر رائع ولكنك تخاطر بأن تكتشف عملية gunicorn الرئيسية التوقف في عملية العامل الخاصة بك فقط بعد 1000 ثانية ، وسوف تفوتك الكثير من الطلبات. كما سيكون من الصعب اكتشافه إذا قام عامل واحد فقط من بين عدة عمال بإنهاء المكالمة. لن أفعل 1000 على الأقل.

@ ivictbor شكرا على lmk. 1000 كمرجع. ومع ذلك ، حصلت على التطبيق قيد التشغيل بمجرد تحميله وهو يعمل بشكل جيد تمامًا.

لقد حصلت على مشكلة الخطأ هذه أيضًا وبعد عدة مرات ، وجدت أن المشكلة ربما تكون:

  1. تكوين Nginx
  2. جونيكورن / أوسجي

إذا قمت بنشر تطبيقك في السحابة مثل GAE ، فلن يظهر أي خطأ تلميح.
يمكنك محاولة إظهار الخطأ باستخدام حل الحالة هذا: https://stackoverflow.com/questions/38012797/google-app-engine-502-bad-gateway-with-nodejs

إذا أثيرت 502 بوابة سيئة ؛
ربما سيكون هناك احتمالان:

  1. gunicorn لا يعمل
  2. حصلت gunicorn على مهلة

شرح السولوشن الكامل هنا: https://www.datadoghq.com/blog/nginx-502-bad-gateway-errors-gunicorn/

آمل أن يتمكن من إصلاح أي شخص حصل على خطأ في مهلة العامل [الحرجة]

مضيفا احتمالية اخرى لمن يجدون هذا الموضوع ...

يمكن أن يحدث هذا أيضًا بسبب فرض عامل عامل الإرساء قيودًا على الموارد منخفضة جدًا بالنسبة لتطبيق الويب الخاص بك. على سبيل المثال ، كان لدي القيود التالية:

services:
  web_app:
    image: blah-blah
    deploy:
      resources:
        limits:
          cpus: "0.25"
          memory: 128M

ومن الواضح أن هذه كانت منخفضة جدًا بالنسبة إلى gunicorn لذلك تلقيت باستمرار الخطأ [CRITICAL] WORKER TIMEOUT حتى أزلت القيود.

بالنسبة إلى gunicorn ، هذه الموارد جيدة تمامًا. لكنك تحتاج إلى ذلك بالفعل
الطائرة لعدد العمال والموارد اللازمة لك
طلب. يبدو أن 128 م و 0.25 وحدة معالجة مركزية منخفضة حقًا لتطبيق الويب
مكتوب بلغة Python .... بشكل عام تحتاج على الأقل 1 core / vcpu و
512 ميجا بايت من ذاكرة الوصول العشوائي كحد أدنى.

يوم الجمعة 26 مارس 2021 الساعة 02:14 ، كولتون هيكس @ . * > كتب:

مضيفا احتمالية اخرى لمن يجدون هذا الموضوع ...

يمكن أن يحدث هذا أيضًا بسبب فرض عامل ميناء يفرض قيودًا على ذلك
منخفضة جدًا بالنسبة لتطبيق الويب. على سبيل المثال كان لدي ما يلي
القيود:

خدمات:
التطبيق على شبكة الإنترنت:
الصورة: بلاه بلاه
نشر:
مصادر:
حدود:
cpus: "0.25"
الذاكرة: 128 م

ومن الواضح أن هذه كانت منخفضة جدًا بالنسبة إلى gunicorn ، لذلك حصلت باستمرار على [الحرجة]
خطأ WORKER TIMEOUT حتى أزلت القيود.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-807855647 ،
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAADRITPZB7BMA6QW7LFNVLTFPNV3ANCNFSM4FDLD5PA
.

>

مرسلة من هاتفي المحمول

- المهلة = 1000 عمل منى. كانت المشكلة عبارة عن آلة GCP ذات موارد منخفضة لوحدة المعالجة المركزية. عملت بشكل جيد على جهازي المحلي مع المهلة الافتراضية.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات