具有Doker的MongoDB和nodejs“ MongoTimeoutError:服务器选择在30000毫秒后超时”

时间:2020-01-02 05:51:20

标签: node.js docker mongoose docker-compose

我将mongoDB与NodeJS后端一起使用。我遇到了问题,下面是docker日志的问题。

{ MongoTimeoutError: Server selection timed out after 30000 ms
    at Timeout.setTimeout [as _onTimeout] (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:897:9)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)
  name: 'MongoTimeoutError',
  reason:
   { Error: connect ECONNREFUSED 127.0.0.1:27017
       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)
     name: 'MongoNetworkError',
     errorLabels: [ 'TransientTransactionError' ],
     [Symbol(mongoErrorContextSymbol)]: {} },
  [Symbol(mongoErrorContextSymbol)]: {} }
(node:1) UnhandledPromiseRejectionWarning: MongoTimeoutError: Server selection timed out after 30000 ms
    at Timeout.setTimeout [as _onTimeout] (/usr/src/app/node_modules/mongodb/lib/core/sdam/topology.js:897:9)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

这是我的Dockerfile

#FROM node:10.12.0
FROM node:latest-alpline

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package.json ./

RUN npm install
# If you are building your code for production
# RUN npm install --only=production

# Bundle app source
COPY . .

EXPOSE 3000
CMD [ "node", "app.js" ]

这是docker-compose.yml

version: "2"
services:
  app:
    container_name: app_test
    restart: always
    build: .
    ports:
      - "3000:3000"
    links:
      - mongo_test
    depends_on:
      - mongo_test
    networks:
      - nodeapp_network
  mongo_test:
    container_name: mongo_test
    image: mongo
    volumes:
      - ./data:/data/db
    ports:
      - "27017:27017"
    networks:
      - nodeapp_network
networks:
  nodeapp_network:
    driver: bridge

以下代码将mongodb连接到节点js中的mongoose:

mongoose.connect('mongodb://mongo_test:27017/collectionName', {useNewUrlParser: true});

如果我使用localhost,127.0.0.1,IP地址而不是mongo_test,则会得到相同的结果。 我已经咨询了几个博客,堆栈溢出。 我该怎么办?

(ps。我不会英语,所以即使单词很尴尬也请理解。谢谢。)

1 个答案:

答案 0 :(得分:0)

经过几次重试,app.js正在连接到数据库,当前配置没有问题

正在发生的事情:

  • docker-compose正在启动Mongodb服务,端口尚未打开
  • docker-compose启动app_test,而app_test尝试连接失败(2至3次)
  • 几秒钟后,Mongodb端口现在在27017上打开
  • 由于您的配置具有restart: always,因此node.js应用程序将重新启动并成功连接到数据库

为避免这些重新启动,您可以这样编写

setTimeout(function() {
 try {
  await mongoose.connect('mongodb://mongo_test:27017/collectionName', 
   { useNewUrlParser: true }
  );
 } catch (error) {
  console.log('Error connecting - retrying in 30 seconds')
}, 30000); // Wait for 30 seconds and try to connect again