簡體   English   中英

econnrefused rabbitMQ docker 容器之間

[英]econnrefused rabbitMQ between docker containers

我正在嘗試設置一個簡單的 docker-compose 文件,其中包括一個 rabbitmq 容器和一個連接到 rabbitmq 的簡單快速服務器。 嘗試從我的快速應用程序連接到 rabbitmq 時出現以下錯誤:

Error: connect ECONNREFUSED 172.19.0.2:5672
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1247:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '172.19.0.2',
  port: 5672
}

我手動檢查了 docker 網絡的 IP 地址,以驗證 172.19.0.2 確實是 rabbitmq 進程,它就是。

這是我的 docker-compose:

version: '3'
services:
  rabbitmq:
    image: rabbitmq:3-management-alpine
    container_name: 'rabbitmq'
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=pass
    ports:
      - 5672:5672
      - 15672:15672
  producerexpress:
    build: ./service1
    container_name: producerexpress
    ports:
      - 3000:3000
    environment:
      - PORT=3000
    depends_on:
      - rabbitmq

以及 express 應用程序及其 docker 文件:

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const amqp = require('amqplib');

const amqpUrl = process.env.AMQP_URL || 'amqp://admin:pass@172.19.0.2:5672';

let channel;
let connection;

connect();

async function connect(){
  try{
    connection = await amqp.connect(amqpUrl);
    channel = await connection.createChannel();

    await channel.assertQueue('chatExchange', {durable: false});
  } catch (err) {
    console.log(err);
  }
}

function sendRabbitMessage(msg) {
  channel.sendToQueue('chatExchange', Buffer.from(msg));
}


app.get('/', (req, res) => {
  let msg = 'Triggered by get request';
  sendRabbitMessage(msg);
  res.send('Sent rabbitmq message!');
});


app.listen(port, () => {
    console.log(`Server started on port ${port}`);
} );
FROM node:16

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

ENV PORT=3000

ENV AMQP_URL=amqp://admin:pass@172.19.0.2:5672

EXPOSE 3000

CMD ["npm", "start"]

這是我第一次使用 docker compose,我在這里找到的所有修復似乎都表明我做的一切都是正確的。 我錯過了什么?

TL;博士
depends_on保證了服務啟動的順序,但這並不能保證它們啟動的進程的任何內容。

在這些情況下,您應該擴展depends_on語句to take into account the health status


首先,您應該避免使硬幣容器的通信依賴於它們的 IP 地址,而是依賴於它們的服務名稱,因為您使用的是 docker 組合。

意思是,而不是amqp://admin:pass@172.19.0.2:5672

你應該使用amqp://admin:pass@rabbitmq:5672


繼續核心問題,您的producerexpress依賴於rabbitmq以實現 function。

因此,您將depends_on語句添加到producerexpress以解決此問題。 但這還不夠,引自https://docs.docker.com/compose/startup-order/

您可以使用depends_on選項控制服務啟動和關閉的順序。 Compose 總是按依賴順序啟動和停止容器,....但是, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it's running

因此,您需要添加health check以保證rabbitmq process has startednot just the container

為了實現這一點,您應該更改您的compose文件

version: '3'
services:
  rabbitmq:
    build: ./rabbitmq
    container_name: 'rabbitmq'
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=pass
    ports:
      - 5672:5672
      - 15672:15672
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:15672"]
      interval: 30s
      timeout: 10s
      retries: 5

  producerexpress:
    build: ./service1
    restart: on-failure
    container_name: producerexpress
    ports:
      - 3000:3000
    environment:
      - PORT=3000
    depends_on:
      rabbitmq:
        condition: service_healthy

為了進行健康檢查,我們需要curl映像中的 curl package,因此添加以下 Z386CCCC94FB75ZFF29

FROM rabbitmq:3-management-alpine
RUN apk update
RUN apk add curl
EXPOSE 5672 15672

最后,為了使此更改兼容,請創建以下目錄結構

./docker-compose.yml
./rabbitmq/
 --- Dockerfile
./service1/
 --- Dockerfile

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM