Redis Windows错误:连接ECONNREFUSED 127.0.0.1:6379,但应用程序正在运行

时间:2019-01-22 02:37:20

标签: docker redis docker-compose ioredis

我的nodejs-redis-docker-compose应用程序出现问题。该应用程序正常运行了几次。但是后来,它开始给我以下错误。我正在使用redis-server v3.2.100 docker 18.09.1 build 4c52b90。我卸载了docker和redis并重新安装了它们,但是我仍然遇到相同的问题。这是错误。

REDIS_DB | 1:C 22 Jan 2019 02:24:00.208 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
REDIS_DB | 1:C 22 Jan 2019 02:24:00.208 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=1, just started
REDIS_DB | 1:C 22 Jan 2019 02:24:00.208 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
REDIS_DB | 1:M 22 Jan 2019 02:24:00.210 * Running mode=standalone, port=6379.
REDIS_DB | 1:M 22 Jan 2019 02:24:00.210 # WARNING: The TCP backlog setting of
511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
REDIS_DB | 1:M 22 Jan 2019 02:24:00.210 # Server initialized
REDIS_DB | 1:M 22 Jan 2019 02:24:00.210 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues
with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
REDIS_DB | 1:M 22 Jan 2019 02:24:00.211 * DB loaded from disk: 0.001 seconds
REDIS_DB | 1:M 22 Jan 2019 02:24:00.211 * Ready to accept connections
MAIN_API    | [nodemon] starting `node --trace-warnings index.js`
MAIN_API    | Unhandled Rejection at: Promise Promise {
MAIN_API    |   <rejected> { Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    |     errno: 'ECONNREFUSED',
MAIN_API    |     code: 'ECONNREFUSED',
MAIN_API    |     syscall: 'connect',
MAIN_API    |     address: '127.0.0.1',
MAIN_API    |     port: 6379 } } reason: Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    | Unhandled Rejection at: Promise Promise {
MAIN_API    |   <rejected> { Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    |     errno: 'ECONNREFUSED',
MAIN_API    |     code: 'ECONNREFUSED',
MAIN_API    |     syscall: 'connect',
MAIN_API    |     address: '127.0.0.1',
MAIN_API    |     port: 6379 } } reason: Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    | ✓-- Redis client pid=>37 Connected
MAIN_API    | --- Redis server pid=>37 is ready
MAIN_API    | ~~~ Testing local redis storage...
MAIN_API    | ✓-- Redis pid=>37 startup test succeeded
MAIN_API    | ✓-- MongoDB pid=>37 Connected
MAIN_API    | ✓-- Server pid=>48 running at port: 5555
MAIN_API    | Unhandled Rejection at: Promise Promise {
MAIN_API    |   <rejected> { Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    |     errno: 'ECONNREFUSED',
MAIN_API    |     code: 'ECONNREFUSED',
MAIN_API    |     syscall: 'connect',
MAIN_API    |     address: '127.0.0.1',
MAIN_API    |     port: 6379 } } reason: Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    | Unhandled Rejection at: Promise Promise {
MAIN_API    |   <rejected> { Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    |     errno: 'ECONNREFUSED',
MAIN_API    |     code: 'ECONNREFUSED',
MAIN_API    |     syscall: 'connect',
MAIN_API    |     address: '127.0.0.1',
MAIN_API    |     port: 6379 } } reason: Error: connect ECONNREFUSED 127.0.0.1:6379
MAIN_API    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
MAIN_API    | ✓-- Redis client pid=>48 Connected
MAIN_API    | --- Redis server pid=>48 is ready
MAIN_API    | ~~~ Testing local redis storage...
MAIN_API    | ✓-- Redis pid=>48 startup test succeeded
MAIN_API    | ✓-- MongoDB pid=>48 Connected

启动nodejs应用程序时会引发错误,但在应用程序启动并运行时它将连接到Redis服务器。


Redis控制台日志

[16308] 21 Jan 18:03:25.425 # Server started, Redis version 3.2.100
[16308] 21 Jan 18:03:25.426 * DB loaded from disk: 0.000 seconds
[16308] 21 Jan 18:03:25.426 * The server is now ready to accept connections on port 6379


我在控制台上运行了netstat -a -n -o,这是相关的部分(我相信)。

TCP    0.0.0.0:6379           0.0.0.0:0              LISTENING       16308
TCP    [::]:6379              [::]:0                 LISTENING       16308

以下是我的文件。


./Dockerfile

FROM node:10.15.0

RUN mkdir -p ./usr/src/MainAPI

WORKDIR /usr/src/MainAPI

COPY ./ ./usr/src/MainAPI

RUN npm install

ARG NODE_VERSION=10.15.0


./docker-compose.yml

version: "3.7"

services:

  # Redis
  redis:
    container_name: REDIS_DB
    image: redis
    ports:
      - "6378:6379"

  # API
  main-api:
    container_name: MAIN_API
    build: ./
    command: ["npm", "start"]
    working_dir: /usr/src/MainAPI
    ports:
      - "5555:5555"
    volumes:
      - ./:/usr/src/MainAPI  


./redisClient.js

const Redis = require("ioredis");
//module.exports = require("redis").createClient(...); => same errors with this module as well

module.exports = new Redis('redis://redis:6379/0');

//module.exports = new Redis('redis://127.0.0.1:6379/0'); =>crashes the app
//module.exports = new Redis('redis://redis:6378/0'); =>crashes the app also


./app.js

"use strict";

const express = require("express");
const { red, green, cyan, yellow } = require("kleur");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const morgan = require("morgan");
const cors = require("cors");
const path = require("path");
const helmet = require("helmet");

const redisClient = require("./redisClient");

const { CLIENT_BASE_URL, API_BASE_URL, MONGO_URI } = process.env;

const isProduction = process.env.NODE_ENV === "production";

const server = express();

const whitelist = [CLIENT_BASE_URL, API_BASE_URL];
const corsOptions = {
  origin: function(origin, callback) {
    if (whitelist.indexOf(origin) !== -1 || !origin) {
      return callback(null, true);
    } else {
      return callback(new Error("Not allowed by CORS"), false);
    }
  }
};

server.use(helmet());

if (isProduction) {
  server.use(cors(corsOptions));
  server.use(morgan("combined"));
} else {
  server.use(morgan("dev"));
}

server.set("trust proxy", 1);

/**
 * Test redis storage on deploy
 */
redisClient.on("connect", function() {
  console.log(
    green("✓-- ") + "Redis client pid=>" + process.pid + " Connected"
  );
});

redisClient.on("ready", function() {
  console.log(cyan("--- Redis server pid=>" + process.pid + " is ready"));
  console.log(cyan("~~~ Testing local redis storage..."));
  const testKey = "key";
  const testValue = "value";
  redisClient.set(testKey, testValue).then(() => {
    redisClient.get(testKey, (error, result) => {
      if (error) {
        console.log(red("✗-- An error occured while testing redis storage"));
        console.error(error);
        return process.exit(1);
      }
      if (!result || result !== testValue) {
        console.log(
          red(
            "✗-- Redis pid=>" + process.pid + " did not pass the startup test"
          )
        );
        console.error(result);
        return process.exit(1);
      }
      console.log(
        green("✓-- Redis pid=>" + process.pid + " startup test succeeded")
      );
    });
  });
});

redisClient.on("error", function(err) {
  console.log(red("✗-- Something went wrong with redis"));
  console.error(err);
  process.exit(1);
});

redisClient.on("end", function() {
  console.log(
    yellow("--- ") + "Redis client pid=>" + process.pid + " closed connection"
  );
});

mongoose.set("useCreateIndex", true);
mongoose.Promise = global.Promise;
mongoose
  .connect(
    MONGO_URI,
    {
      useNewUrlParser: true
    }
  )
  .then(() => {
    console.log(green("✓-- ") + "MongoDB pid=>" + process.pid + " Connected");
  })
  .catch(err => {
    console.log(red("✗--Database Connection"));
    console.error(err);
    process.exit(1);
  });

server.use(
  bodyParser.urlencoded({
    extended: false
  })
);
server.use(bodyParser.json());

require("./controlers/home")(server);
require("./controlers/user")(server);
require("./controlers/admin")(server);

if (isProduction) {
  server.use(express.static("client/build"));

  server.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
  });
}

module.exports = server;

我没有在服务器上调用.listen(...),因为它已导出到另一个文件(index.js)。

谢谢

2 个答案:

答案 0 :(得分:0)

我正在回答自己的问题。我在代码中找到了导致此问题的原因。实际上,我开始使用npm agendaMongoDB来调度应用程序中的某些任务。后来我切换到使用npm bull的{​​{1}}。我创建了如下队列实例。

Redis

应该是

const Queue = require("bull");

const emailQueue = new Queue("emails");

因为我没有为模块指定redis设置,所以它无法连接到服务器。我完全忘记了我有另一个使用Redis的模块。该应用似乎正常运行的原因是,const Queue = require("bull"); const emailQueue = new Queue("emails", { redis: { port: 6379, host: "redis-server" } }); 已连接到Redis,而express未连接。我会弄清楚,如果我尝试使用功能,那么Bull是过程的一部分。我还简化了bullDockerfile文件,使其仅包含必要的步骤。


/ Dockerfile

docker-compose.yml


/docker-compose.yml

FROM node:alpine # create image with NodeJS version alpine included 

WORKDIR /usr/app # set working directory of the app to be /usr/app/. create folder /usr/app if it does not exist already. The following operations would then happen inside /usr/app

COPY ./package.json ./ # copy package.json file into current directory, which is /usr/app according to previous step

RUN npm install # install dependencies 

COPY ./ ./ # add the rest of the files to /usr/app

CMD ["npm", "start"] # run 'npm start' when the container is starting

我不需要其他任何东西来运行该应用程序。通过在我的应用程序中将服务名称简单地赋予version: "3" services: # Redis redis-server: # the name of the redis service becomes the host name in my application container_name: REDIS_SERVER image: 'redis' # API main-api: container_name: MAIN_API build: ./ ports: - "5555:5555" ,该模块将确定在哪里可以找到服务器。即在ioredis部分中的here。在我的情况下,服务器名称为links,因此redis-serverioredis的主机名也将为bull,端口号为redis-server。谢谢@DavidMaze @yeaseol和...

答案 1 :(得分:-1)

该端口已绑定到6378,因此您需要访问6378
您可以使用主机名redis吗? (设置了吗?)
试试这个:
module.exports = new Redis('redis://{docker-server-hostname}:6378');

最好的选择是将link设置为docker-compose。

main-api:
    container_name: MAIN_API
    build: ./
    command: ["npm", "start"]
    working_dir: /usr/src/MainAPI
    ports:
      - "5555:5555"
    volumes:
      - ./:/usr/src/MainAPI  
    links:
      - {your-redis-container-name}

尝试一下:
module.exports = new Redis('redis://{your-redis-container-name}:6379');