web-dev-qa-db-ja.com

docker-composeを使用したRabbitMQコンテナーへの接続

あるコンテナでRabbitMQを実行し、別のコンテナでワーカープロセスを実行したい。ワーカープロセスはRabbitMQにアクセスする必要があります。

これらをdocker-composeで管理したいと思います。

これは今のところ私のdocker-compose.ymlファイルです:

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"

  worker:
    build: ./worker
    depends_on:
      - rabbitmq
    # Allow access to docker daemon
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

それで、RabbitMQポートを公開しました。ワーカープロセスは、次のURLを使用してRabbitMQにアクセスします。

amqp://guest:guest@rabbitmq:5672/

公式チュートリアルで使用するものですが、localhostrabbitmqと交換されています。これは、コンテナがコンテナ名と同じホスト名で 検出可能である必要があるためです:

デフォルトでは、Composeはアプリに単一のネットワークを設定します。サービスの各コンテナはデフォルトネットワークに参加し、そのネットワーク上の他のコンテナから到達可能であり、コンテナ名と同じホスト名でそれらのコンテナによって検出可能です。

これを実行するたびに、接続拒否エラーが表示されます。

Recreating ci_rabbitmq_1 ... done                                                                                                                                                    
Recreating ci_worker_1   ... done                                                                                                                                                    
Attaching to ci_rabbitmq_1, ci_worker_1                                                                                                                                              
worker_1    | dial tcp 127.0.0.1:5672: connect: connection refused                                                                                                                   
ci_worker_1 exited with code 1        

ホスト名としてlocalhostを指定したにもかかわらず、rabbitmqであるIP 127.0.0.1を使用しているため、これが興味深いと思います。私はdocker networkingの専門家ではないので、これが望ましいかもしれません。

必要に応じて詳細情報を提供させていただきます。


編集

ほとんど同じ質問があります hererabbitmqを開始する前に、workerが起動して実行されるまで待つ必要があると思います。私はこれをヘルスチェックで試しました:

version: "2.1"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"
    healthcheck:
      test: [ "CMD", "nc", "-z", "localhost", "5672" ]
      interval: 10s
      timeout: 10s
      retries: 5

  worker:
    build: .
    depends_on:
      rabbitmq:
        condition: service_healthy

(異なるバージョンに注意してください)。しかし、これは機能しません-それは常に不健康として失敗します。

6
haz

あぁ!それを私が直した。 @Ijazはまったく正しかった-RabbitMQサービスは開始に時間がかかり、私のワーカーは実行前に接続を試みます。

遅延を使用しようとしましたが、RabbitMQが通常より長くかかったときに失敗しました。

これはまた、より大きなアーキテクチャ上の問題を示しています-生産中にキューサービス(私の場合はRabbitMQ)がオフラインになるとどうなりますか?今、私のサイト全体が失敗します。組み込みの冗長性とポーリングが必要です。

この この関連する答え で説明したように、docker-compose 3+

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - 5672
      - 15672
    healthcheck:
      test: [ "CMD", "nc", "-z", "localhost", "5672" ]
      interval: 5s
      timeout: 15s
      retries: 1

  worker:
    image: worker
    restart: on-failure
    depends_on:
      - rabbitmq

これで、workerコンテナは数回再起動しますが、rabbitmqコンテナは正常ではありません。 rabbitmqは、nc -z localhost 5672成功-つまり、キューがライブになったとき!

6
haz

別のコンテナからサービスにアクセスするだけの場合、ホスト上のポートを公開/マッピングする必要はないかもしれません。

ドキュメントから:

Exposeホストマシンに公開せずにポートを公開します-リンクされたサービスにのみアクセスできます。指定できるのは内部ポートのみです。

expose:
 - "3000"
 - "8000"

したがって、次のようになります。

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"

  worker:
    build: ./worker
    depends_on:
      - rabbitmq
    # Allow access to docker daemon
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

また、rabitmqがポートでサーバーへの準備が整ったときにのみ接続するようにしてください。

2
Ijaz Ahmad Khan