celery -A proj report
の出力を問題に含めました。master
ブランチに対して存在することを確認しました。tasks.py
from celery import Celery
celery = Celery('tasks', broker='pyamqp://guest@localhost//')
@celery.task
def add(x, y):
return x + y
@celery.on_after_configure.connect
def add_periodic():
celery.add_periodic_task(10.0, add.s(2,3), name='add every 10')
if __name__ == '__main__':
add_periodic()
ステップ1:rabbitmqがアップしています
rabbitmq 1186 1 0 Nov12? 00:00:00 / bin / sh / usr / sbin / rabbitmq-サーバー
ステップ2:tasks.pyを実行しますpython tasks.py
ステップ3:ビートワーカーを開始するcelery -A tasks -l info beat
セロリビートv4.0.0(latentcall)が始まります。
__ --... __ --_
LocalTime-> 2016-11-12 17:37:58
構成->
。 ブローカー-> amqp:// guest:** @localhost :5672 //
。 ローダー-> celery.loaders.app.AppLoader
。 スケジューラー-> celery.beat.PersistentScheduler
。 db-> celerybeat-スケジュール
。 ログファイル-> [stderr] @%INFO
。 maxinterval-> 5.00分(300秒)
[2016-11-12 17:37:58,912:INFO / MainProcess]ビート:開始中...
スケジューラーが10秒ごとにadd()関数をトリガーすることを期待しています。
add()関数はトリガーされません。
ターミナルに例外はありません。 私は何かが恋しいですか?
私は同じ問題を抱えていました:(
あなたの例は私にとってうまくいきます。
注:シグナルハンドラーは** kwargsを受け入れる必要があります。受け入れない場合、将来的にエラーが発生します。
あなたの例を使用して
# file: tasks.py
from celery import Celery
celery = Celery('tasks', broker='pyamqp://guest@localhost//')
@celery.task
def add(x, y):
return x + y
@celery.on_after_configure.connect
def add_periodic(**kwargs):
celery.add_periodic_task(10.0, add.s(2,3), name='add every 10')
私は次のようにビートサービスを開始します:
$ celery -A tasks beat -l debug
celery beat v4.0.0 (latentcall) is starting.
__ - ... __ - _
LocalTime -> 2016-12-01 11:54:56
Configuration ->
. broker -> amqp://guest:**<strong i="11">@localhost</strong>:5672//
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]@%DEBUG
. maxinterval -> 5.00 minutes (300s)
[2016-12-01 11:54:56,511: DEBUG/MainProcess] Setting default socket timeout to 30
[2016-12-01 11:54:56,511: INFO/MainProcess] beat: Starting...
[2016-12-01 11:54:56,517: DEBUG/MainProcess] Current schedule:
<ScheduleEntry: celery.backend_cleanup celery.backend_cleanup() <crontab: 0 4 * * * (m/h/d/dM/MY)>
<ScheduleEntry: add every 10 tasks.add(2, 3) <freq: 10.00 seconds>
[2016-12-01 11:54:56,517: DEBUG/MainProcess] beat: Ticking with max interval->5.00 minutes
[2016-12-01 11:54:56,528: DEBUG/MainProcess] Start from server, version: 0.9, properties: {'information': 'Licensed under the MPL. See http://www.rabbitmq.com/', 'product': 'RabbitMQ', 'copyright': 'Copyright (C) 2007-2016 Pivotal Software, Inc.', 'capabilities': {'exchange_exchange_bindings': True, 'connection.blocked': True, 'authentication_failure_close': True, 'direct_reply_to': True, 'basic.nack': True, 'per_consumer_qos': True, 'consumer_priorities': True, 'consumer_cancel_notify': True, 'publisher_confirms': True}, 'cluster_name': 'rabbit<strong i="12">@grain</strong>', 'platform': 'Erlang/OTP', 'version': '3.6.4'}, mechanisms: [u'AMQPLAIN', u'PLAIN'], locales: [u'en_US']
[2016-12-01 11:54:56,531: INFO/MainProcess] Scheduler: Sending due task add every 10 (tasks.add)
[2016-12-01 11:54:56,534: DEBUG/MainProcess] using channel_id: 1
[2016-12-01 11:54:56,535: DEBUG/MainProcess] Channel open
[2016-12-01 11:54:56,537: DEBUG/MainProcess] beat: Synchronizing schedule...
[2016-12-01 11:54:56,537: DEBUG/MainProcess] tasks.add sent. id->af224838-cf72-4d0d-9076-1c39cdbeffb8
[2016-12-01 11:54:56,537: DEBUG/MainProcess] beat: Waking up in 9.97 seconds.
[2016-12-01 11:55:06,519: INFO/MainProcess] Scheduler: Sending due task add every 10 (tasks.add)
[2016-12-01 11:55:06,520: DEBUG/MainProcess] tasks.add sent. id->907cf307-e36f-455a-97a8-441c79b8ab92
こんにちは、私は同じ問題を抱えています。 しかし、私はスレッドでプログラム的にセロリを始めようとしています。 多分それが原因です。
これは私のスレッドです:
from __future__ import absolute_import, unicode_literals
import threading
from celery import current_app
from celery.bin import worker
app = current_app._get_current_object()
class CeleryThread(threading.Thread):
def __init__(self):
super(CeleryThread, self).__init__()
self.app = app
self.worker = worker.worker(app=self.app)
self.options = {
'broker': 'amqp://guest:guest<strong i="7">@localhost</strong>:5672//',
'loglevel': 'INFO',
'traceback': True,
}
app.add_periodic_task(5.0, test.s('hello'), name='add every 10')
def run(self):
self.worker.run(**self.options)
@app.task
def test(args1):
print args1
そしてこれを起動するためのmain.py
celery_thread = CeleryThread()
# used to kill the thread when the main program stop
# celery_thread.daemon = True
celery_thread.start()
私のコンソール出力は
-------------- celery<strong i="14">@ubuntu</strong> v4.0.0 (latentcall)
---- **** -----
--- * *** * -- Linux-4.4.0-51-generic-x86_64-with-Ubuntu-16.04-xenial 2016-12-03 14:33:10
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: default:0x7f75775bfc50 (.default.Loader)
- ** ---------- .> transport: amqp://guest:**<strong i="15">@localhost</strong>:5672//
- ** ---------- .> results: disabled://
- *** --- * --- .> concurrency: 4 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. kalliope.core.CrontabManager2.CeleryThread.test
[2016-12-03 14:33:10,458: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2016-12-03 14:33:10,466: INFO/MainProcess] mingle: searching for neighbors
[2016-12-03 14:33:11,486: INFO/MainProcess] mingle: all alone
[2016-12-03 14:33:11,515: INFO/MainProcess] celery<strong i="16">@ubuntu</strong> ready.
オプションを忘れましたか? 出力@askに「スケジューラ」が設定されていることがわかります
助けてくれてありがとう。
@ liuallen1981と同じ設定と同じ問題。 誰もが何が起こっているのか理解していますか? 今のところ私は使用する必要があります
celery.conf.beat_schedule = {
'do-something-periodically': {
'task': 'tasks.my_task',
'schedule': 3.0,
},
}
on_after_configure.connect
デコレータでsetup_periodic_tasks
関数を使用する代わりに。
+1この問題もあります。
+1この問題もあります。
セロリバージョン4.0.2(潜在呼び出し)
+1この問題もあります。
+1この問題もあります。 @ liuallen1981のコードを
セロリ:4.0.2
定期的なタスクを実行するには、 -B
オプションを使用してワーカーを起動するときにスケジューラーも呼び出す必要があります。
celery -A proj worker -B
タスクがアプリから自動検出されるdjangoアプリケーションでセロリを使用する場合は、 on_after_configure
代わりにon_after_finalize
シグナルを使用する必要があります。
参照:
http://stackoverflow.com/questions/40712678/setup-periodic-task/40727526
http://stackoverflow.com/questions/41119053/connect-new-celery-periodic-task-in-django
-Bは本番用ではなく、少なくとも私の場合はすでに実行されているBeatsスケジューラーを起動するだけです。
セロリ(4.0.2)と同じ問題を抱えている+1
ここで同じ問題...
ビートサービスを開始するだけで、タスクを実行するワーカーも開始する必要があります。
+1
ここに同じ問題
ここで同じ問題、
コールバック内に何かを出力しようとすると、コールバックが呼び出されていないようですが、RabbitMQは機能しています(コードでタスクをトリガーすると正常に機能します)
@celery.on_after_configure.connect
def setup_periodic_tasks(**kwargs):
print('after connect')
(py35) ➜ celery -A celery.beat beat
celery beat v4.0.2 (latentcall) is starting.
__ - ... __ - _
LocalTime -> 2017-08-08 02:42:18
Configuration ->
. broker -> amqp://**:**@**:5672//
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]@%WARNING
. maxinterval -> 5.00 minutes (300s)
これを解決するために、動的にadd_periodic_task
celery.conf.beat_schedule
代わりにCelery config
ライブラリをステップスルーしたところ、 on_after_configure
シグナルが発生した後、シグナルリスナーが作成/接続されていることがわかりました。 (シグナルリスナーをapp/tasks.py
していましたが、機能していませんでした。)
Djangoのアプリ準備完了シグナルはおそらくCeleryの構成後に実行され、これまでのところうまく機能していると私は考えました。
注:Celeryの構成に実際に必要なものと、Celeryが構成される前にapp.readyが起動する可能性があるかどうかはわかりません...ただし、少なくともランタイムエラーがスローされると思います。
私のapp/apps.py
からのサンプルコード:
from django.apps import AppConfig
import django.db.utils
from celery_app import app as celery_app
from celery.schedules import crontab
import utils.cron
class MyAppConfig(AppConfig):
name = 'app'
verbose_name = "MyApp"
def ready(self):
print("MyAppConfig.ready invoked.")
import app.signals
print("* * * Setting up periodic tasks!")
import app.models
import app.tasks
for cron in app.models.CronTask.objects.all():
celery_app.add_periodic_task(
crontab(**utils.cron.parse_crontab_expression_to_celery(cron.frequency)),
app.tasks.do_cron.s(cron.id),
name='do cron'
)
また、 settings.py
新しいAppConfig
を使用するようにINSTALLED_APPS
を指定する必要があることに注意してください。
INSTALLED_APPS = [
# ...
'app.apps.MyAppConfig',
]
良いアプローチまたは修正は、1)Celeryがすでに構成されているかどうかを確認し、構成されている場合はすぐに実行し、2)Celeryが構成されていない場合は、 @celery.on_after_configure.connect
を使用してリスナーを追加する新しいデコレータを作成することです。
現状では、私たちの多くがこの問題に遭遇したため、ドキュメントには問題があります。
CCing @rustanacexd @viennaddは、タスクを動的にスケジュールする必要がある場合にこの修正を試すことができるようにするためですか?
私の2セントをそこに置いて、私はこれに少し気づき、私のタスクのいくつかを並べ替えなければならなくなった。 起動する予定のタスクが約8つありますが、次のことが発生することに気付きました。
例:
@celery.on_after_configure.connect
def setup_periodic_tasks(**kwargs):
celery.add_periodic_task(5.0, do_thing_b.s(), name='Test B')
celery.add_periodic_task(4.9, do_thing_a.s(), name='Test A')
このように注文すると、 do_thing_b
で上書きされるため、 do_thing_a
が起動することはありません。 元々は両方とも5
に設定されていましたが、発砲するのは1つだけ.1
だけオフセットして、それが修正されるかどうかを確認することでした。 サイコロはありません。 それから私はそれらを注文して、低い方が最初に発砲し、高い方が次に発砲するようにしました。 すなわち:
@celery.on_after_configure.connect
def setup_periodic_tasks(**kwargs):
celery.add_periodic_task(4.9, do_thing_b.s(), name='Test B')
celery.add_periodic_task(5.0, do_thing_a.s(), name='Test A')
また、いくつかのcrontab()
を使用していますが、これらはいくつかの作業として実行するのは謎のようなものですが、実行しないものもありますが、上記と同じ問題であると思われます。 これらの間隔は通常X時間/日ごとに発生するように設定されているため、完全には試していません。通常、それらが存在することを忘れています。
たぶん、この種の振る舞いはドキュメントに記載されているか、この振る舞いはあまり意味がありませんが、私は別のうさぎの穴を掘り下げます。 参考までに、RMQとcelery4.1.0の代わりにRedisを使用しています。
私はこの仕事をすることができました。 ここで私の答えを確認してください:
@ prasanna-balaramanそれはうまくいくようです、提案をありがとう!
私にとって同じ問題:私は別の解決策をテストします: https :
閉鎖。 それでも表示され、コードやドキュメントの提案がある場合は、plzがこの問題を参照するPRを送信してください。
setup_periodic_tasksで例外が発生した場合、それがサイレントに抑制されることに気付くのに少し時間がかかりました。
関数はここで呼び出されます: https :
何か問題が発生した場合、例外は応答にのみ保存され、再発生やログは記録されません。
https://github.com/celery/celery/blob/master/celery/utils/dispatch/signal.py#L276
したがって、私の提案は、setup_periodic_tasksをできるだけ単純に保つことです。
お役に立てれば!
@ chiang831それを改善するための提案はありますか? もしそうなら、plzはprを送るか、セロリユーザーのメーリングリストでディスカッションを開きます
on_after_finalize
それらを定義することは、私にとってうまくいったことです(非djangoセロリアプリ)。
@app.on_after_finalize.connect
def app_ready(**kwargs):
"""
Called once after app has been finalized.
"""
sender = kwargs.get('sender')
# periodic tasks
speed = 15
sender.add_periodic_task(speed, update_leases.s(),
name='update leases every {} seconds'.format(speed))
ちょうどこれに遭遇し、以前の解決策のどれも私のために働いていませんでした。 これを引き起こす正確なシナリオは混乱を招き、ref-counting / gcの動作と装飾された関数の正確な存続期間に依存します。
Signal.connectは、デフォルトでは、シグナルハンドラへの弱参照のみを保持します。 これは、Signalオブジェクト(シグナルをワイヤリングする短命のオブジェクトがシグナルハンドラによって存続されるべきではない)の他のユースケースには意味がありますが、この場合は非常に驚くべきことです。
私の特定のユースケースは、新しい定期的なタスクを簡単に追加できるようにするデコレータでした。
def call_every_5_min(task):
@app.on_after_configure.connect
def register_task(sender, **_):
sender.add_periodic_task(collect_every_m*60, task.signature())
<strong i="8">@call_every_5_min</strong>
<strong i="9">@task</strong>
def my_celery_task(_):
pass
修正は、強力な参照を明示的に要求することです。
def call_every_5_min(task):
def register_task(sender, **_):
sender.add_periodic_task(collect_every_m*60, task.signature())
app.on_after_configure.connect(register_task, weak=False)
ドキュメントの例は、装飾された関数がモジュールまたはクラススコープにある場合にのみ機能します。その場合、モジュールまたはクラスは引き続き関数への強力な参照を保持します。 それ以外の場合、唯一の強力な参照は、で定義されているスコープの最後で消滅します。
ドキュメントを変更してweak=False
を渡すことをお勧めします。これは、上記の場合に機能するはずです。 ただし、Djangoのコンテキストでこれを明示的にテストしていません。
定期的なタスクを実行するには、
-B
オプションを使用してワーカーを起動するときにスケジューラーも呼び出す必要があります。
celery -A proj worker -B
タスクがアプリから自動検出されるdjangoアプリケーションでセロリを使用する場合は、
on_after_configure
代わりにon_after_finalize
シグナルを使用する必要があります。参照:
http://stackoverflow.com/questions/40712678/setup-periodic-task/40727526
http://stackoverflow.com/questions/41119053/connect-new-celery-periodic-task-in-django
on_after_finalize
使用すると、 app_name.celery.py
の最後でpython -m celery -A app_name worker -l info --autoscale=20,5 -BE
プロセスがブロックされます。
@ liuallen1981と同じ設定と同じ問題。 誰もが何が起こっているのか理解していますか? 今のところ私は使用する必要があります
celery.conf.beat_schedule = { 'do-something-periodically': { 'task': 'tasks.my_task', 'schedule': 3.0, }, }
on_after_configure.connect
デコレータでsetup_periodic_tasks
関数を使用する代わりに。
これは代わりに私のために働きます。
この問題を解決しようとしている場合は、最初にDockerエンジンを再起動してください。これは、システムのバグを示している可能性があります。
この問題をバグではなくクローズする必要がありますか?
@auvipyわからない。 セロリのバグのようです
これは私たちが修正しなければならないバグです。
最も参考になるコメント
定期的なタスクを実行するには、
-B
オプションを使用してワーカーを起動するときにスケジューラーも呼び出す必要があります。celery -A proj worker -B
タスクがアプリから自動検出されるdjangoアプリケーションでセロリを使用する場合は、
on_after_configure
代わりにon_after_finalize
シグナルを使用する必要があります。参照:
http://stackoverflow.com/questions/40712678/setup-periodic-task/40727526
http://stackoverflow.com/questions/41119053/connect-new-celery-periodic-task-in-django