首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用码头组合连接到RabbitMQ容器

用码头组合连接到RabbitMQ容器
EN

Stack Overflow用户
提问于 2018-10-28 12:19:42
回答 4查看 30.7K关注 0票数 27

我希望在一个容器中运行RabbitMQ,在另一个容器中运行一个工作进程。辅助进程需要访问RabbitMQ。

我想通过docker-compose来管理这些。

到目前为止,这是我的docker-compose.yml文件:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
amqp://guest:guest@rabbitmq:5672/

这是他们在官方教程中使用的,但是localhost被替换为rabbitmq,因为容器应该是可以使用与容器名称相同的主机名发现:

默认情况下,Compose为您的应用程序设置一个网络。服务的每个容器都加入了默认网络,并且可以被该网络上的其他容器访问,并且可以在与容器名称相同的主机名上被它们发现。

每当我运行它时,我都会得到一个连接被拒绝的错误:

代码语言:javascript
运行
复制
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        

我觉得这很有趣,因为它使用的是IP 127.0.0.1 (我认为)是localhost,尽管我将rabbitmq指定为主机名。我不是码头人关系网的专家,所以这也许是我想要的。

如果需要,我很乐意提供更多的信息!

编辑

有一个几乎相同的问题,这里。我认为我需要等到rabbitmq启动并运行之后才能启动worker。我试着做了健康检查:

代码语言:javascript
运行
复制
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

(注意不同的版本)。然而,这是行不通的--它总是失败的,因为它不健康。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-10-29 02:17:00

啊哈!我修好了。@Ijaz是完全正确的-- RabbitMQ服务需要一段时间才能启动,我的工作人员试图在它运行之前进行连接。

我试着使用延迟,但是当RabbitMQ比平常花费更长的时间时,它失败了。

这也表明了一个更大的架构问题--如果队列服务(在我的例子中是RabbitMQ)在生产过程中脱机会发生什么?现在我的整个网站都失败了。需要有一些内置的冗余和轮询。

如本这个相关的答案所述,我们可以在docker-compose 3+中使用健康检查。

代码语言:javascript
运行
复制
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立即变得健康--即当队列处于活动状态时!

票数 25
EN

Stack Overflow用户

发布于 2021-05-29 15:53:53

以下是正确的工作示例:

代码语言:javascript
运行
复制
    version: "3.8"

    services:

    rabbitmq:
        image: rabbitmq:3.7.28-management
        #container_name: rabbitmq
        volumes:
            - ./etc/rabbitmq/conf:/etc/rabbitmq/
            - ./etc/rabbitmq/data/:/var/lib/rabbitmq/
            - ./etc/rabbitmq/logs/:/var/log/rabbitmq/
        environment:
            RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE:-secret_cookie}
            RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-admin}
            RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-admin}
        ports:
            - 5672:5672    #amqp
            - 15672:15672  #http
            - 15692:15692  #prometheus
        healthcheck:
        test: [ "CMD", "rabbitmqctl", "status"]
        interval: 5s
        timeout: 20s
        retries: 5

    mysql:
        image: mysql
        restart: always
        volumes:
        - ./etc/mysql/data:/var/lib/mysql
        - ./etc/mysql/scripts:/docker-entrypoint-initdb.d
        environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: mysqldb
        MYSQL_USER: ${MYSQL_DEFAULT_USER:-testuser}
        MYSQL_PASSWORD: ${MYSQL_DEFAULT_PASSWORD:-testuser}
        ports:
        - "3306:3306"
        healthcheck:
        test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
        timeout: 20s
        retries: 10

    trigger-batch-process-job:
        build: .
        environment:
        - RMQ_USER=${RABBITMQ_DEFAULT_USER:-admin}
        - RMQ_PASS=${RABBITMQ_DEFAULT_PASS:-admin}
        - RMQ_HOST=${RABBITMQ_DEFAULT_HOST:-rabbitmq}
        - RMQ_PORT=${RABBITMQ_DEFAULT_PORT:-5672}
        - DB_USER=${MYSQL_DEFAULT_USER:-testuser}
        - DB_PASS=${MYSQL_DEFAULT_PASSWORD:-testuser}
        - DB_SERVER=mysql
        - DB_NAME=mysqldb
        - DB_PORT=3306
        depends_on:
        mysql:
            condition: service_healthy
        rabbitmq:
            condition: service_healthy
票数 9
EN

Stack Overflow用户

发布于 2018-10-28 13:16:24

如果您只是从另一个容器访问服务,则可能不需要公开/映射主机上的端口。

从文件中:

公开公开端口,而不将它们发布到主机上--它们只能被链接的服务访问。只能指定内部端口。 曝光:- "3000“- "8000”

所以应该是这样的:

代码语言:javascript
运行
复制
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,只有当它准备好服务器在端口上。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53031439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档