【问题标题】:Redis Windows Error: connect ECONNREFUSED 127.0.0.1:6379 but appilcation is workingRedis Windows 错误:连接 ECONNREFUSED 127.0.0.1:6379 但应用程序正在运行
【发布时间】:2019-01-23 20:43:57
【问题描述】:

我的 nodejs-redis-docker-compose 应用程序有问题。该应用程序正常运行了几次。但后来,它开始给我以下错误。我正在使用redis-server v3.2.100docker 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)。

谢谢

【问题讨论】:

  • redis:6379 应该是正确的,使用服务的 YAML 块的名称作为主机名,使用其内部端口作为端口号。但是,它不会有 IP 地址 127.0.0.1。你能检查一下你是否正确地更新和重建了所有东西吗?
  • @DavidMaze 是的,我删除了图像并重建了所有内容,但我仍然遇到同样的错误。奇怪的是该应用程序运行良好。不知道问题出在哪里真是令人烦恼。我尝试了在 github 上找到的不同类型的配置。他们工作,但仍然得到相同的确切错误。正如我在帖子中所说,我什至卸载了 redis 和 docker 并重新安装。依然没有。谢谢

标签: docker redis docker-compose ioredis


【解决方案1】:

我正在回答我自己的问题。我在我的代码中找到了导致问题的原因。事实上,我开始使用npm agenda,它使用MongoDB,在我的应用程序中调度一些任务。我后来切换到npm bull,它使用的是Redis。我创建了如下的队列实例。

const Queue = require("bull");

const emailQueue = new Queue("emails");

应该是的

const Queue = require("bull");

const emailQueue = new Queue("emails", {
  redis: { port: 6379, host: "redis-server" }
});

因为我没有指定模块的redis设置,所以无法连接到服务器。我完全忘记了我有另一个使用 redis 的模块。该应用程序似乎工作的原因是因为express 连接到redis 而bull 没有。如果我尝试使用公牛是该过程的一部分的功能,我会弄清楚这一点。我还简化了我的Dockerfiledocker-compose.yml 文件,只包含必要的步骤。


/Dockerfile

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


/docker-compose.yml

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,该模块将找出在哪里可以找到服务器。这就是links 部分中的here。在我的例子中,服务器名称是redis-server,所以ioredisbull 的主机名也是redis-server 和端口号6379。谢谢@DavidMaze @yeaseol,还有...

【讨论】:

    【解决方案2】:

    端口绑定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');

    【讨论】:

    • 容器间连接始终使用内部服务器端口,如果存在,则为 ports: 中的 second 数字。您不需要 ports:links: 设置。问题中的redis:6379 似乎应该是对的。
    • @DavidMaze @yeaseol 我试过linksnetworksdepends_on。但我仍然遇到同样的错误。可能是我的windows电脑有问题,我不知道。在过去的几个月里,我开始看到在使用 Windows 机器时成为一名高效的开发人员是多么困难。还是谢谢你。我会继续寻找答案。
    猜你喜欢
    • 2017-07-06
    • 2017-05-16
    • 2022-08-21
    • 2020-08-27
    • 1970-01-01
    • 2023-03-18
    • 2021-03-14
    • 2020-12-25
    • 2019-01-03
    相关资源
    最近更新 更多