簡體   English   中英

第一次嘗試時無法將節點連接到 docker 容器中的 mongoDB

[英]Cannot connect Node to mongoDB in docker container on first try

我正在嘗試對接 Node.js 應用程序,該應用程序使用 mongoose 連接到 MongoDB。 當連接 URL 為: mongodb://localhost:27017/deposit時,只要我從 shell 運行node index.js ,它就會成功如果我重新啟動計算機,然后嘗試使用命令docker-compose up運行 dockerized 項目(在 url 中使用mongo而不是localhost ),則無法連接到 MongoDB。 但是在我再次嘗試相同的命令后,它就成功了。

所以我的問題是為什么節點無法連接到 MongoDB 在計算機重新啟動后第一次嘗試?

PS。 Docker 在我嘗試時正在運行

連接.js

const mongoose = require('mongoose');

const connection = "mongodb://mongo:27017/deposit";

const connectDb = () => {
    mongoose.connect(connection, {useNewUrlParser: true,  useUnifiedTopology: true}).then(res => console.log("Connected to DB"))
    .catch(err => console.log('>> Failed to connect to MongoDB, retrying...'));
};

module.exports = connectDb;

Dockerfile

 FROM node:latest

 RUN mkdir -p /app
 WORKDIR /app
 #/usr/src/app
 COPY package.json /app
 RUN npm install

 COPY . /app

 EXPOSE 7500

#  ENTRYPOINT ["node"]

 CMD ["node", "src/index.js"]

docker-compose.yml

version: "3"
services:
        deposit:
            container_name: deposit
            image: test/deposit
            restart: always
            build: .
            network_mode: host
            ports:
              - "7500:7500"
            depends_on:
              - mongo
        mongo:
              container_name: mongo
              image: mongo
              volumes:
                - /data:/data/db
              network_mode: host
              ports:
                - '27017:27017'

在您的情況下,節點應用程序在 mongo 准備好之前啟動。 有兩種方法可以解決這個問題: 在您的 docker-compose 或您的應用程序中處理它。 您可以使用wait-for-it.sh或編寫wrapper script (兩者都在此處描述)以確保您的節點應用程序在數據庫准備好后啟動。 正如 docker 文檔所引用的那樣,最好在您的應用程序中處理這個問題:

要處理這個問題,請將您的應用程序設計為在發生故障后嘗試重新建立與數據庫的連接。 如果應用程序重試連接,它最終可以連接到數據庫。

最好的解決方案是在您的應用程序代碼中執行此檢查,無論是在啟動時還是由於任何原因失去連接時

您可以按如下方式實施 mongo 重試(在答案中描述):

var connectWithRetry = function() {
  return mongoose.connect(mongoUrl, function(err) {
    if (err) {
      console.error('Failed to connect to mongo on startup - retrying in 5 sec', err);
      setTimeout(connectWithRetry, 5000);
    }
  });
};
connectWithRetry();

如評論中所述,數據庫可能尚未准備好接受連接,因此一種方法是添加重試邏輯或另一種選擇是

serverSelectionTimeoutMS -

使用 useUnifiedTopology,MongoDB 驅動程序將嘗試找到一個服務器來發送任何給定的操作,並繼續重試serverSelectionTimeoutMS毫秒。 如果未設置,MongoDB 驅動程序默認使用 30000(30 秒)。

所以試試下面的選項

const mongoose = require('mongoose');

const uri = 'mongodb://mongo:27017/deposit?retryWrites=true&w=majority';
mongoose.connect(uri, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  serverSelectionTimeoutMS: 50000
}).catch(err => console.log(err.reason));

但是,如果您初始化數據庫腳本變得更大,則需要更多時間,因此如果這不起作用,則使用重試邏輯 go。 在上面的腳本中,它將等待 50 秒。

暫無
暫無

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

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