1

私はなんとか単一のマシンを手に入れて作業DjangoするRabbitMQことができました。ここCeleryからの指示に従いました。今、私はそれらを一緒に動作させたいと思っていますが、それらが異なるサーバー上にある状況にあります。についても、についても知りたくありません。DjangoCeleryCeleryDjango

Djangoしたがって、基本的には、いくつかのメッセージをキューに送信したいだけですRabbitMQ(おそらく ID、タスクの種類、おそらく他の情報)。次に、RabbitMQそのメッセージを (可能な場合)Celery別のサーバーに公開します。Celery/Django基本的にはどちらか一方を置き換えやすいアーキテクチャが欲しい。

今、私は次Djangoのようないくつかの呼び出しを持っています

create_project.apply_async(args, countdown=10)

これを、RabbitMQ への同様の呼び出しに直接置き換えたいと思います (前述のようにDjango、依存すべきではありませんCelery)。次に、(可能な場合)RabbitMQ通知し、その仕事をします(おそらくインターフェイスを介して対話します)。CeleryCeleryDjangoREST

Celeryまた、 2 つ以上のサーバーにワーカーを配置する必要がありRabbitMQ、メッセージのフィールドに応じてそのうちの 1 つだけに通知したいと考えています。これが複雑すぎる場合は、(異なるマシン上の) すべてのタスクを次のようにチェックインすることができます: これはあなたがすべきことです (メッセージの IP アドレス フィールドをチェックするなど)。

どうすればこれを達成できますか?可能であれば、理論的な説明だけでなく、コードと構成の例を好むでしょう。

編集:

私のユースケースでは、セロリは総オーバーヘッドだと思います。カスタム クライアントを使用したシンプルな RabbitMQ ルーティングで十分です。私はすでに単純なユース ケース (1 つのサーバー) を試しましたが、完全に機能します。通信をマルチサーバー化するのは簡単なはずです。私はセロリが好きではありません。それは「魔法のよう」で、あまりにも多くの詳細を隠し、設定が簡単ではありません。しかし、他の人の意見に興味があるので、この質問はそのままにしておきます。

4

1 に答える 1

6

それの短所

どうすればこれを達成できますか?

Celery は、タスク名とシリアル化された一連のパラメーターのみをメッセージ本文として送信します。つまり、あなたのシナリオはセロリの運用方法と完全に一致しています。

可能であれば、理論的な説明だけでなく、コードと構成の例を好むでしょう。

クライアント アプリ、つまり Django アプリの場合、次のようにスタブ タスクを定義します。

@task
def foo():
    pass

Celery 処理の場合、リモート サーバーで、実行する実際のタスクを定義します。

@task
def foo():
    pass

タスクが両側で同じ Python パッケージに存在することが重要です (つまりapp.tasks.py、そうでない場合、Celery はメッセージを実際のタスクに一致させることができません。

Celery アプリを Django アプリでローカルに使用できる CELERY_ALWAYS_EAGER=Trueようにしない限り、を設定した場合、これは Django アプリがテスト不能になることも意味することに注意してください。tasks.py

さらに単純な代替手段

上記のスタブ タスクに代わる方法は、タスクを名前で送信することです。

>>> app.send_task('tasks.add', args=[2, 2], kwargs={})
<AsyncResult: 373550e8-b9a0-4666-bc61-ace01fa4f91d>

メッセージパターンについて

また、2 つ以上のサーバーに Celery ワーカーを配置する必要があり、RabbitMQ がメッセージ内のフィールドに応じてそのうちの 1 つだけに通知するようにします。

RabbitMQ はいくつかのメッセージング パターンを提供します。それらのチュートリアルは非常によく書かれており、的を射ています。あなたが望むもの (1 つのワーカーによって処理される 1 つのメッセージ) は、他に何もしない場合のデフォルトである (少なくとも Celery では) 単純なキュー/交換のセットアップで自明に達成されます。特定のタスクに参加する/特定のメッセージに応答するために特定のワーカーが必要な場合は、RabbitMQ のキューと交換の概念と連携して動作する Celery のタスクルーティングを使用します。

トレードオフ

私のユースケースでは、セロリは総オーバーヘッドだと思います。カスタム クライアントを使用した単純な RabbitMQ ルーティングで十分です。私はすでに単純なユース ケース (1 つのサーバー) を試しましたが、完全に機能します。

もちろん、RabbitMQ が提供する下位レベルの API を処理する必要があるという犠牲を払って、RabbitMQ をそのまま使用することもできます。Celery は、基本的に単純な Python 関数またはメソッドを使用して、プロデューサー/コンシューマーのシナリオを非常に簡単に構築できるようにするタスクの抽象化を追加します。これは、RabbitMQ または Celery のいずれかのより良い/悪い判断ではないことに注意してください。常にエンジニアリング上の決定と同様に、トレードオフが関係しています。

  • Celery を使用すると、RabbitMQ API の柔軟性の一部が失われる可能性がありますが、開発が容易になり、開発速度が向上し、デプロイの複雑さが軽減されます。基本的には機能します。

  • RabbitMQ を直接使用すると柔軟性が得られますが、これに伴い、展開が複雑になり、自分で管理する必要があります。

プロジェクトの要件に応じて、どちらのアプローチも有効な場合があります。

十分に高度な技術は、魔法と見分けがつきません;-)

私はセロリが好きではありません。それは「魔法のよう」で、あまりにも多くの詳細を隠し、設定が簡単ではありません。

私は反対することを選択します。Arthur C. Clarke の感覚では「魔法のような」ものかもしれませんが、単純な RabbitMQ セットアップと比較すると、構成は確かにかなり簡単です。もちろん、RabbitMQ のセットアップも行っている場合は、実際には何も得られない抽象化のレイヤーが追加されるだけかもしれません。多分あなたの開発者はそうするでしょうか?

于 2014-12-24T00:51:36.913 に答える