web-dev-qa-db-ja.com

セロリタスクを受信したが実行していない

受け取ったが実行されないCeleryタスクがあります。 Python 2.7とCelery4.0.2を使用しています。私のメッセージブローカーはAmazonSQSです。

これはcelery workerの出力です:

$ celery worker -A myapp.celeryapp --loglevel=INFO
[tasks]
  . myapp.tasks.trigger_build

[2017-01-12 23:34:25,206: INFO/MainProcess] Connected to sqs://13245:**@localhost//
[2017-01-12 23:34:25,391: INFO/MainProcess] celery@ip-111-11-11-11 ready.
[2017-01-12 23:34:27,700: INFO/MainProcess] Received task: myapp.tasks.trigger_build[b248771c-6dd5-469d-bc53-eaf63c4f6b60]

-Ofairの実行時にcelery workerを追加しようとしましたが、役に立ちませんでした。役立つかもしれない他のいくつかの情報:

  • セロリは常に8つのタスクを受け取りますが、ピックアップされるのを待っているメッセージは約100あります。
  • タスクは実際には4〜5回に1回程度、実際にはwill実行して完了しますが、その後再びスタックします。
  • これはps auxの結果です。 3つの異なるプロセスでセロリを実行していることに注意してください(理由はわかりません)。そのうちの1つは、タスクなどを完了していなくても、CPU使用率が99.6%です。

プロセス:

$ ps aux | grep celery
nobody    7034 99.6  1.8 382688 74048 ?        R    05:22  18:19 python2.7 celery worker -A myapp.celeryapp --loglevel=INFO
nobody    7039  0.0  1.3 246672 55664 ?        S    05:22   0:00 python2.7 celery worker -A myapp.celeryapp --loglevel=INFO
nobody    7040  0.0  1.3 246672 55632 ?        S    05:22   0:00 python2.7 celery worker -A myapp.celeryapp --loglevel=INFO

設定:

CELERY_BROKER_URL = 'sqs://%s:%s@' % (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY.replace('/', '%2F'))
CELERY_BROKER_TRANSPORT = 'sqs'
CELERY_BROKER_TRANSPORT_OPTIONS = {
    'region': 'us-east-1',
    'visibility_timeout': 60 * 30,
    'polling_interval': 0.3,
    'queue_name_prefix': 'myapp-',
}
CELERY_BROKER_HEARTBEAT = 0
CELERY_BROKER_POOL_LIMIT = 1
CELERY_BROKER_CONNECTION_TIMEOUT = 10

CELERY_DEFAULT_QUEUE = 'myapp'
CELERY_QUEUES = (
    Queue('myapp', Exchange('default'), routing_key='default'),
)

CELERY_ALWAYS_EAGER = False
CELERY_ACKS_LATE = True
CELERY_TASK_PUBLISH_RETRY = True
CELERY_DISABLE_RATE_LIMITS = False

CELERY_IGNORE_RESULT = True
CELERY_SEND_TASK_ERROR_EMAILS = False
CELERY_TASK_RESULT_EXPIRES = 600

CELERY_RESULT_BACKEND = 'Django-db'
CELERY_TIMEZONE = TIME_ZONE

CELERY_TASK_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['application/json']

CELERYD_PID_FILE = "/var/celery_%N.pid"
CELERYD_Hijack_ROOT_LOGGER = False
CELERYD_PREFETCH_MULTIPLIER = 1
CELERYD_MAX_TASKS_PER_CHILD = 1000

報告書:

$ celery report -A myapp.celeryapp

software -> celery:4.0.2 (latentcall) kombu:4.0.2 py:2.7.12
            billiard:3.5.0.2 sqs:N/A
platform -> system:Linux Arch:64bit, ELF imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:sqs results:Django-db
14

私も同じ問題を抱えていました。少し検索した後、Celeryワーカーのコマンドラインに--without-gossip --without-mingle --without-heartbeat -Ofairを追加するための解決策を見つけました。したがって、あなたの場合、ワーカーコマンドはcelery worker -A myapp.celeryapp --loglevel=INFO --without-gossip --without-mingle --without-heartbeat -Ofairである必要があります

2
Vishnu

同じ問題があります。ヴィシュヌの答えは私のために働きます。これらの追加パラメーターをworkerコマンドに追加する必要のない別のソリューションがあるかもしれません。

私の問題は、タスクコードの途中で他のモジュールをインポートすることによって引き起こされます。ワーカーを起動すると、セロリは使用されているすべてのモジュールをフェッチしているようで、.pyファイルの先頭のみを調べます。実行中はエラーは発生せず、終了するだけです。すべての「import」と「from ... import ...」をコードファイルの先頭に移動すると、機能します。

0
Haotian Deng

Celery 3.1でこれを解決するには、ワーカーのゴシップ(--without-gossip)を無効にするだけで十分でした。 CELERY_ACKS_LATEが有効になっていると、バグが原因でこのワーカー間通信がハングするようです。タスクは実際に受信されますが、確認または実行されることはありません。ワーカーを停止すると、それらはキューに戻されます。

ゴシップの docs から:

これは、ワーカーが他のワーカーが何をしているかを知っており、オフラインになるかどうかを検出できることを意味します。現在、これはクロック同期にのみ使用されますが、将来追加される可能性が多く、すでにこれを利用する拡張機能を作成できます。

したがって、とにかくこの機能を使用していない可能性があり、さらにそれはブローカーの負荷を増加させます。

調査する時間はありませんが、最新のCeleryでこれをテストし、それでも問題が発生する場合は問題を開くことをお勧めします。この動作が予想される/避けられない場合でも、それを文書化する必要があります。

0
kontextify