2016-12-08 11 views
14

私たちの環境では、AWSでRabbitMQとCeleryを使用して、多くのノードで並列にタスクを実行しています。AWS ELBとRabbitMQを使用したセロリー接続の削除

最近、私たちはRabbitMQを3ノードのクラスタにし、HAポリシーを設定し、ポート5672のAWS弾性ロードバランサ(ELB)をすべての3ノードに追加しました。私たちのセロリの労働者とクライアントコードはすべて、ブローカーURLとしてELB DNSを使用します。

この変更以来、非同期タスクが完了するのを待つと、例外IOError: Socket closedがスローされます。

ELBは、60秒後にすべてのアイドル接続をシャットダウンします。私たちは完了するのに数時間かかる作業があります。

BROKER_HEARTBEATを、ワーカー側の接続切断数が60未満の値に設定します。しかし、クライアントの接続を維持するための設定を見つけることはできません。

セロリで長時間実行されるタスクを待つ正しい方法ですか?

まだテストしていない1つの回避策は、正常に終了するまでAsyncResult.wait()メソッドを呼び出すことです。だから、例えば:

我々が使用
async_result = task.delay(params) 

while True: 
    try: 
     async_result.wait() 
     break 
    except IOError: 
     pass 

  1. RabbitMQの3.6.5
  2. セロリ3.1.20
  3. セロリバックエンドpyamqp
  4. セロリ結果バックエンドは、RPC
です
+1

ここで私は外に出かけるつもりですが、あなたは自分自身に古典的なXY問題があると言います。バットからすぐに、非同期作業を待っている間、スレッドを一時停止することに伴うかなりの臭いがあります。第2に、一般的なケースでは、ELB/Route 53は何百万と何百万という要求に対応するように設計されています。この考え方を念頭において、彼らがあなたのソケットを何時間も開いたままにしておくと、かなり早く圧倒されるでしょう。私はあなたがタコで床を畳んでいるのを見いだすだろうと思っています。あなたはあきらめて、モップを買ってください。 – nsfyn55

答えて

3

私はAWS Eでタイムアウトを延長する必要があると信じていますポンド。何が起こっているのかは、タスクが完了する前に接続が閉じられていることです。これを行うには、次のコマンドを発行します。

elb-modify-lb-attributes myTestELB --connection-settings "idletimeout=3600" --headers 

これで、タスクを完了するまでに1時間かかります。これに関する詳細については、https://aws.amazon.com/blogs/aws/elb-idle-timeout-control/を参照してください。

時間が足りない場合は、接続プーリングを無効にする必要があります。セロリの設定にこれらの2つの設定を追加してください

BROKER_POOL_LIMIT = None 
BROKER_TRANSPORT_OPTIONS = {'confirm_publish': True} 

秒は、オーバーヘッドが追加されるため、パフォーマンスが低下します。長期間の作業があるので、これは問題ではないかもしれません。 2番目の設定は必要ないかもしれませんが、ロードバランサの背後にいることを前提にしてお勧めします。この設定は、メッセージが受信され、処理中に失われないことを確認します。

もう1つの選択肢は、長いタスクを小さなタスクにも分割することです。これはより多くのコードを意味するかもしれませんが、長期的には価値があるかもしれません。

関連する問題