我想在一个容器中运行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/
它们在官方教程中使用的是哪个,但是localhost
已被替换为rabbitmq
,因为容器应为discoverable with a hostname identical to the container name:
默认情况下,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
我发现这很有趣,因为即使我将127.0.0.1
指定为主机名,它也使用了IP localhost
(我认为)为rabbitmq
。我不是Docker网络方面的专家,所以也许这是理想的。
如果需要,我很乐意提供更多信息!
修改
存在一个几乎相同的问题here。我认为我需要等到rabbitmq
启动后再运行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
(请注意其他版本)。但是,这不起作用-总是会因为不健康而失败。
答案 0 :(得分:2)
如果您只是从另一个容器访问服务,也许不需要公开/映射主机上的端口。
从文档中:
公开公开端口,而无需将其发布到主机上-只有链接的服务才能访问它们。仅内部端口 可以指定。
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。
答案 1 :(得分:2)
啊哈!我修好了它。 @Ijaz完全正确-RabbitMQ服务需要一段时间才能启动,而我的工作人员会在运行之前尝试进行连接。
我尝试使用延迟,但是当RabbitMQ比平时花费更长的时间时,此操作失败。
这也表明存在较大的体系结构问题-如果排队服务(在我的情况下为RabbitMQ)在生产期间脱机怎么办?现在,我的整个网站都失败了。需要一些内置的冗余和轮询。
正如对此this related answer所述,我们可以在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
立即变得健康!
答案 2 :(得分:1)
这是正确的工作示例:
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
答案 3 :(得分:0)
docker compose v3.8
最干净的方式
version: "3.8"
worker:
build: ./worker
rabbitmq:
condition: service_healthy
rabbitmq:
image: library/rabbitmq
ports:
- 5671:5671
- 5672:5672
healthcheck:
test: [ "CMD", "nc", "-z", "localhost", "5672" ]
interval: 5s
timeout: 10s
retries: 3