Celery: خطأ OS: المقبس مغلق في عامل الكرفس مع الحدث الصغير

تم إنشاؤها على ١٤ يونيو ٢٠١٨  ·  23تعليقات  ·  مصدر: celery/celery

إصدار الكرفس: 4.2.0

خطوات التكاثر

عامل ميناء compose.yml

version: '2'

services:
  worker:
    build: .
    depends_on:
      - rabbitmq

  rabbitmq:
    image: rabbitmq:alpine

ملف Dockerfile

FROM alpine

RUN apk add --no-cache build-base python3 python3-dev
RUN pip3 install celery eventlet

CMD celery -b amqp://rabbitmq worker -P eventlet --loglevel=DEBUG
$ docker-compose up --build

سلوك متوقع

يبقى العامل على اتصال دون أخطاء

السلوك الفعلي

بعد 3 دقائق من بدء التشغيل ، أبلغ العامل عن عدة أخطاء باستخدام التتبع ، على غرار ما يلي:

[2018-06-14 20:11:44,213: WARNING/MainProcess] Traceback (most recent call last):
[2018-06-14 20:11:44,213: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/hubs/poll.py", line 114, in wait
    listener.cb(fileno)
[2018-06-14 20:11:44,214: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120, in loop
    connection.drain_events(timeout=1.0)
[2018-06-14 20:11:44,214: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
    return self.transport.drain_events(self.connection, **kwargs)
[2018-06-14 20:11:44,215: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103, in drain_events
    return connection.drain_events(**kwargs)
[2018-06-14 20:11:44,216: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
    while not self.blocking_read(timeout):
[2018-06-14 20:11:44,217: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
    frame = self.transport.read_frame()
[2018-06-14 20:11:44,217: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
    frame_header = read(7, True)
[2018-06-14 20:11:44,218: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 426, in _read
    raise IOError('Socket closed')
[2018-06-14 20:11:44,218: WARNING/MainProcess] OSError: Socket closed
[2018-06-14 20:11:44,219: WARNING/MainProcess] Removing descriptor: 7

بالإضافة إلى ذلك ، يُبلغ خادم rabbitmq عن تحذيرات مشابهة لما يلي (تكرر مرتين):

2018-06-14 20:11:44.209 [warning] <0.586.0> closing AMQP connection <0.586.0> (172.19.0.3:42678 -> 172.19.0.2:5672):
missed heartbeats from client, timeout: 60s
Eventlet Workers Pool Gevent Workers Pool RabbitMQ Broker Bug Report

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

auvipy لماذا أغلقت هذا؟ المشكلة لا تزال قائمة.

ال 23 كومينتر

لاحظ أنه عند استخدام prefork بدلاً من eventlet ، لا يزال خادم rabbitmq يبلغ عن التحذير من دقات القلب المفقودة ، ولكن لا توجد تحذيرات مطبوعة في العامل:

2018-06-14 20:36:04.807 [warning] <0.698.0> closing AMQP connection <0.698.0> (172.19.0.3:46040 -> 172.19.0.2:5672):
missed heartbeats from client, timeout: 60s

وفشل gevent مع ظهور رسالة خطأ مماثلة لـ eventlet :

[2018-06-14 20:43:29,908: WARNING/MainProcess] Traceback (most recent call last):
[2018-06-14 20:43:29,908: WARNING/MainProcess] File "src/gevent/_waiter.py", line 119, in gevent.__waiter.Waiter.switch
[2018-06-14 20:43:29,908: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120, in loop
    connection.drain_events(timeout=1.0)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
    return self.transport.drain_events(self.connection, **kwargs)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103, in drain_events
    return connection.drain_events(**kwargs)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
    while not self.blocking_read(timeout):
[2018-06-14 20:43:29,910: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
    frame = self.transport.read_frame()
[2018-06-14 20:43:29,910: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
    frame_header = read(7, True)
[2018-06-14 20:43:29,911: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 418, in _read
    s = recv(n - len(rbuf))
[2018-06-14 20:43:29,911: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/gevent/_socket3.py", line 380, in recv
    return _socket.socket.recv(self._sock, *args)
[2018-06-14 20:43:29,912: WARNING/MainProcess] ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-14 20:43:29,912: WARNING/MainProcess] 2018-06-14T20:43:29Z
[2018-06-14 20:43:29,913: WARNING/MainProcess] <built-in method switch of gevent.__greenlet_primitives.TrackedRawGreenlet object at 0x7f791830ce88> failed with ConnectionResetError

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

FROM alpine

RUN apk add --no-cache build-base python3 python3-dev
RUN pip3 install https://github.com/celery/celery/zipball/master#egg=celery https://github.com/celery/billiard/zipball/master#egg=billiard https://github.com/celery/py-amqp/zipball/master#egg=amqp https://github.com/celery/kombu/zipball/master#egg=kombu https://github.com/celery/vine/zipball/master#egg=vine eventlet gevent

CMD celery -b amqp://rabbitmq worker -P eventlet --loglevel=DEBUG

هذا يطابق ما نمر به. في قائمة انتظار واحدة ، لدينا العديد من العمال task_acks_late = True و worker_prefetch_multiplier = 1 ولدينا مزيج من المهام طويلة الأمد والمهام القصيرة.

يؤدي الرجوع إلى الإصدار 3.x من الكرفس إلى "اختفاء" هذه المشكلة

لمعلوماتك

في البداية ، لم تكن عمليات إعادة المحاولة تعمل عند استخدام الكرفس 4.1.0 و kombu 4.1.0. بعد التحديث إلى 4.2.0 و 4.2.1 على التوالي ، بدأت عمليات إعادة المحاولة في العمل ولكن بدأت رسائل المهلة نفسها في الظهور وبدا أن المهام قد تم تسليمها بشكل صحيح ولكن لم تتم معالجتها من قبل العمال. نحن نستخدم prefork

-amqp==2.2.2
+amqp==1.4.9
-billiard==3.5.0.3
+billiard==3.3.0.23
-celery==4.2.0
+celery==3.1.23
-kombu==4.2.1
+kombu==3.0.34
-pyramid-celery==3.0.0
+pyramid-celery==2.0.0

يستخدم اتصال الوسيط إعداد نبضات القلب من ملف تكوين التطبيق افتراضيًا (منذ الإصدار 4.2.0 ، # 4148).

التكوين والافتراضيات - التوثيق

broker_heartbeat

وسائل النقل المدعومة:

  • pyamqp

الافتراضي: 120.0 (تم التفاوض عليه بواسطة الخادم).

يمكنك محاولة تعيين broker_heartbeat=0 . أتمنى أن يساعدك هذا.

@ y0ngdi قمت بتعيين broker_heartbeat=0 ، هناك انخفاض في الخطأ ، لكنه لا يزال موجودًا.

amqp==2.3.2
celery==4.2.0
gevent==1.3.4
greenlet==0.4.13
kombu==4.2.0
أبلغ العامل عن عدة أخطاء باستخدام التتبع:
[2018-06-22 09:41:21,467: INFO/MainProcess] sync with celery<strong i="11">@device_producer_tasks</strong>
[2018-06-22 09:41:21,468: ERROR/MainProcess] Control command error: error(32, 'Broken pipe')
Traceback (most recent call last):
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/celery/worker/pidbox.py", line 46, in on_message
    self.node.handle_message(body, message)
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 129, in handle_message
    return self.dispatch(**body)
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 112, in dispatch
    ticket=ticket)
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 135, in reply
    serializer=self.mailbox.serializer)
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 265, in _publish_reply
    **opts
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/messaging.py", line 181, in publish
    exchange_name, declare,
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/messaging.py", line 203, in _publish
    mandatory=mandatory, immediate=immediate,
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/channel.py", line 1732, in _basic_publish
    (0, exchange, routing_key, mandatory, immediate), msg
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/abstract_channel.py", line 50, in send_method
    conn.frame_writer(1, self.channel_id, sig, args, content)
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/method_framing.py", line 166, in write_frame
    write(view[:offset])
  File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/transport.py", line 275, in write
    self._write(s)
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe

لقد واجهت هذه المشكلة مع الكرفس 4.2 و Eventlet ولكن لم يتم العثور على حل مثالي

لقد أجريت تحقيقًا صغيرًا. يقوم الكرفس بإنشاء اتصال جديد ولكنه لا يستدعي heartbeat_check أجله. ينتج عن هذا خادم RabbitMQ يغلق الاتصال. لقد واجهت هذا الخطأ في اتصال الأمر (على سبيل المثال ، stats ، ping ، ..)

مثال بسيط:

from __future__ import absolute_import, unicode_literals
from celery import Celery

app = Celery(
    'myapp',
    broker='amqp://guest@localhost//',
)
app.conf.broker_heartbeat = 5


if __name__ == '__main__':
    app.start()

قم بتشغيل المثال

$ python3 example.py worker -l DEBUG

سجلات RabbitMQ

2018-06-27 19:49:41.109 [info] <0.471.1> accepting AMQP connection <0.471.1> (127.0.0.1:42744 -> 127.0.0.1:5672)
2018-06-27 19:49:41.111 [info] <0.471.1> connection <0.471.1> (127.0.0.1:42744 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:41.116 [info] <0.479.1> accepting AMQP connection <0.479.1> (127.0.0.1:42746 -> 127.0.0.1:5672)
2018-06-27 19:49:41.118 [info] <0.479.1> connection <0.479.1> (127.0.0.1:42746 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:41.131 [info] <0.500.1> accepting AMQP connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672)
2018-06-27 19:49:41.133 [info] <0.500.1> connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:56.135 [warning] <0.500.1> closing AMQP connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672):
missed heartbeats from client, timeout: 5s

محاولة إرسال أمر بعد إغلاق الاتصال بواسطة RabbitMQ:

$ celery inspect ping

يطبع سجل عامل الكرفس هذا عندما يتلقى الأمر:

[2018-06-27 19:51:25,638: DEBUG/MainProcess] pidbox received method ping() [reply_to:{'exchange': 'reply.celery.pidbox', 'routing_key': '5a7fe1f1-be67-397f-879c-d939ea3c076e'} ticket:d80183f3-a236-4057-841b-6b8cd2926917]
[2018-06-27 19:51:25,639: ERROR/MainProcess] Control command error: ConnectionResetError(104, 'Connection reset by peer')
Traceback (most recent call last):
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/celery/worker/pidbox.py", line 46, in on_message
    self.node.handle_message(body, message)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 129, in handle_message
    return self.dispatch(**body)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 112, in dispatch
    ticket=ticket)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 135, in reply
    serializer=self.mailbox.serializer)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 265, in _publish_reply
    **opts
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 181, in publish
    exchange_name, declare,
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 194, in _publish
    [maybe_declare(entity) for entity in declare]
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 194, in <listcomp>
    [maybe_declare(entity) for entity in declare]
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 102, in maybe_declare
    return maybe_declare(entity, self.channel, retry, **retry_policy)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/common.py", line 129, in maybe_declare
    return _maybe_declare(entity, declared, ident, channel, orig)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/common.py", line 135, in _maybe_declare
    entity.declare(channel=channel)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/entity.py", line 185, in declare
    nowait=nowait, passive=passive,
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/channel.py", line 614, in exchange_declare
    wait=None if nowait else spec.Exchange.DeclareOk,
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method
    conn.frame_writer(1, self.channel_id, sig, args, content)
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame
    write(view[:offset])
  File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/transport.py", line 275, in write
    self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-27 19:51:25,647: DEBUG/MainProcess] Closed channel #2
[2018-06-27 19:51:25,647: DEBUG/MainProcess] using channel_id: 2
[2018-06-27 19:51:25,648: DEBUG/MainProcess] Channel open

سبب محتمل للخطأ

أعتقد أن هناك اتصالًا تم إنهاؤه بعد ذلك من جانب الخادم لأنه لا يتم استدعاء kombu.connection.Connection.heartbeat_check() بشكل متكرر في المثيل.

أرى نفس المشكلة مع gevent.

الحل البديل مع broker_heartbeat = 0 يعمل بالنسبة لي.

الإصدارات المثبتة:

amqp==2.2.2
celery==4.2.0
eventlet==0.23.0
kombu==4.2.1

عامل:
celery -A celery_app worker --loglevel=info -P eventlet

تم اختبار PS على Windows 10 مع Python 2 و 3.

auvipy : لماذا يتم الإغلاق؟ لم يتم إصلاح المشكلة ...

هل عمل @ stojan-jovic الحل البديل؟

يبدو الأمر وكأنه نعم ، لكن الحل ليس إصلاحًا للخلل.
ولا يزال يؤدي إلى إهدار الكثير من الوقت في البحث عن حل من قبل المزيد من الأشخاص كل يوم.

إذا توصلت إلى إصلاح محتمل ، فسيتم إعادة فتحه.

يبدو أن الحل البديل مع broker_heartbeat = 0 يعمل بالنسبة لي من أجل الكرفس 4.2.0 و gevent 1.2.2 (python 2) / RabbitMQ 3.7.8. على الأقل لم يتم إنهاء المكالمة مع العمال في مهلة الستينيات الافتراضية بالنسبة لي.

جانغو 1.8.4 ، بايثون 2.7.12
ظهرت المشكلة بعد الترقية من 3.1.25 إلى 4.2.1
CELERY_BROKER_HEARTBEAT = 0 في settings.py تم حل هذه المشكلة.

auvipy لماذا أغلقت هذا؟ المشكلة لا تزال قائمة.

djlambert إنه معروف بإغلاق القضايا / العلاقات العامة بدون سبب.

أي تحديثات على هذا؟ الحل ليس إصلاحًا للخلل.

لا تتردد في التحقيق في المشكلة gvdmarck لأنك تواجه هذا ، سيكون من الأسهل عليك معرفة السبب الجذري.

جانغو 1.8.4 ، بايثون 2.7.12
ظهرت المشكلة بعد الترقية من 3.1.25 إلى 4.2.1
CELERY_BROKER_HEARTBEAT = 0 في settings.py تم حل هذه المشكلة.

يجب أن تكون BROKER_HEARTBEAT بدلاً من CELERY_BROKER_HEARTBEAT؟

amqp == 2.2.2

أحاول تشغيل عامل الكرفس بهذا التكوين ، لكن عامل الكرفس لم يبدأ.
الأمر الذي أستخدمه هو كما يلي
تشغيل عامل الكرفس pipenv -A src.celery_app -l debug -P eventlet
لكنني لا أرى أي سجل لبدء تشغيل الكرفس ، أو أي شيء يعود مباشرة إلى موجه windows cmd.

@ stojan-jovic ، هل يمكنك إخباري بكيفية تهيئة بيئة الكرفس.

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