web-dev-qa-db-fra.com

Connexion au conteneur RabbitMQ avec docker-compose

Je veux exécuter RabbitMQ dans un conteneur et un processus de travail dans un autre. Le processus de travail doit accéder à RabbitMQ.

Je voudrais que ceux-ci soient gérés par docker-compose.

C'est mon docker-compose.yml fichier jusqu'à présent:

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

J'ai donc exposé les ports RabbitMQ. Le processus de travail accède à RabbitMQ à l'aide de l'URL suivante:

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

C'est ce qu'ils utilisent dans le didacticiel officiel, mais localhost a été remplacé par rabbitmq, car les conteneurs doivent être détectable avec un nom d'hôte identique au nom du conteneur: =

Par défaut, Compose configure un réseau unique pour votre application. Chaque conteneur d'un service rejoint le réseau par défaut et est à la fois accessible par d'autres conteneurs sur ce réseau et détectable par eux à un nom d'hôte identique au nom du conteneur.

Chaque fois que je lance ceci, j'obtiens une erreur de connexion refusée:

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        

Je trouve cela intéressant car il utilise l'IP 127.0.0.1 qui (je pense) est localhost, même si j'ai spécifié rabbitmq comme nom d'hôte. Je ne suis pas un expert en réseautage docker, alors peut-être que cela est souhaité.

Je suis heureux de fournir plus d'informations si nécessaire!


Modifier

Il y a une question presque identique ici . Je pense que je dois attendre que rabbitmq soit opérationnel avant de démarrer worker. J'ai essayé de le faire avec un bilan de santé:

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

(Notez la version différente). Cela ne fonctionne pas, cependant - il échouera toujours car il n'est pas sain.

6
haz

Ah! Je l'ai corrigé. @Ijaz était tout à fait correct - le service RabbitMQ prend du temps à démarrer et mon collaborateur essaie de se connecter avant de fonctionner.

J'ai essayé d'utiliser un délai, mais cela a échoué lorsque le RabbitMQ a pris plus de temps que d'habitude.

Cela indique également un problème architectural plus important - que se passe-t-il si le service de mise en file d'attente (RabbitMQ dans mon cas) se déconnecte pendant la production? En ce moment, mon site entier échoue. Il doit y avoir une redondance et une interrogation intégrées.

Comme décrit ceci cette réponse connexe , nous pouvons utiliser des contrôles de santé dans 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

Maintenant, le conteneur worker redémarrera plusieurs fois tandis que le conteneur rabbitmq restera malsain. rabbitmq devient immédiatement sain lorsque nc -z localhost 5672 réussit - c'est-à-dire lorsque la file d'attente est active!

6
haz

Vous n'avez peut-être pas besoin d'exposer/mapper les ports sur l'hôte si vous accédez simplement au service à partir d'un autre conteneur.

De la documentation:

Expose Exposez les ports sans les publier sur la machine hôte - ils ne seront accessibles qu'aux services liés. Seul le port interne peut être spécifié.

expose:
 - "3000"
 - "8000"

Donc ça devrait être comme ça:

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

assurez-vous également de vous connecter à rabitmq uniquement lorsqu'il est prêt à être serveur sur le port.

2
Ijaz Ahmad Khan