Redis Windows Error: connect ECONNREFUSED 127.0.0.1:6379, но приложение работает
У меня проблема с моим приложением 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 ответа
Я отвечаю на свой вопрос. Я нашел то, что вызывает проблему в моем коде. На самом деле я начал использовать 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
не. Я бы понял это, если бы попытался использовать функцию, которая является частью процесса. Я также упростил мой Dockerfile
а также docker-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
раздел. В моем случае имя сервера redis-server
поэтому имя хоста для ioredis
а также bull
также будет redis-server
и номер порта 6379
, Спасибо @DavidMaze @yeaseol и...
Порт связан с 6378
так что вам нужно получить доступ 6378
,
И можете ли вы использовать имя хоста redis
? (Вы установили это?)
Попробуй это:module.exports = new Redis('redis://{docker-server-hostname}:6378');
или же
Лучший вариант - установить link
докер-сочинять.
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');