【发布时间】:2021-05-25 08:59:26
【问题描述】:
我正在使用 redis 包,我遇到了很多连接问题,连接突然出现 ECONNREFUSED。
我怀疑是因为我做了错误的连接管理。
这个项目的问题是我的应用程序向 api(ip 和端口)发送参数,api 必须根据这些值创建一个连接,获取一些数据并返回它。 我有数百台服务器,所以我不知道如何管理所有这些连接。
到目前为止,我在一个连接中管理它。这就是为什么我认为它失败了。
目前看起来像这样..
let redisClient;
const killRedis = () => {
redisClient.quit()
console.log("redis client shut down")
}
const createRedisClient = async (port, url) => {
redisClient = require('redis').createClient(port, url, {
no_ready_check: true,
db: 1
})
redisClient.on('error', function (err) {
console.log('Error ' + err);
killRedis();
return undefined;
});
redisClient.on('connect', function () {
console.log('Connected to Redis');
});
return redisClient;
}
module.exports = { createRedisClient, }
它有点工作,但最终会失败,不时拒绝连接。
我在路线中像下面这样使用它。
const scanAll = async (port, url) => {
const redisClient = await createRedisClient(port, url)
if (!redisClient) return 500
const scan = promisify(redisClient.scan).bind(redisClient);
const found = [];
let cursor = '0';
do {
const reply = await scan(cursor, 'MATCH', '*');
cursor = reply[0];
found.push(...reply[1]);
} while (cursor !== '0');
return found;
};
/* Return all the users id */
router.post('/user/list', async function (req, res, next) {
const data = await scanAll(req.body.port, req.body.ip);
console.log("data ", data)
if (data === 500) {
res.status(500).json({
error: "Error, server connection refused"
})
}
else if (data.length === 0) {
res.status(204).json(data)
} else {
res.status(200).json(data);
}
})
如何进行正确的连接管理?
编辑:我的新尝试,但我认为在进行 2 次同时请愿时我的人脉已经泛滥
let connections = []
findConnection = (ip, port) => {
let connection = connections.filter(i => i.ip == ip && i.port == port)
console.log("pre")
console.log(connection)
if (connection && connection.connection) {
console.log("opcion1: ", connection.ip)
console.log("connection already exists")
return connection[0].connection
} else {
console.log("opcion2")
console.log(connections)
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
return connections.filter(i => i.ip == ip && i.port == port)[0].connection
}
}
const createRedisClient = async (port, url) => {
let redisClient = findConnection(url, port)
redisClient.on('error', function (err) {
console.log('Error ' + err);
redisClient.quit()
return undefined;
});
redisClient.on('connect', function () {
console.log('Connected to Redis');
});
return redisClient;
}
module.exports = { createRedisClient, }
我注意到我收到以下错误
MaxListenersExceededWarning:可能的 EventEmitter 内存泄漏 检测到。添加了 11 个错误侦听器。使用emitter.setMaxListeners() 增加限制
编辑:最后一个实现问题
My current implementation is the following
let connections = []
const killRedis = (redisClient, ip, port) => {
redisClient.quit()
connections = connections.filter((i) => { return i.ip !== ip && i.port != port })
}
const subscribe = (redisClient, url, port) => {
redisClient.on('error', function (err) {
console.log('Error ' + err);
killRedis(redisClient, url, port)
return undefined;
});
redisClient.on('connect', function () {
console.log('Connected to Redis');
return redisClient;
});
}
findConnection = (ip, port) => {
let connection = connections.filter(i => i.ip == ip && i.port == port)
if (connection && connection.length > 0) {
subscribe(connection[0].connection)
return connection[0].connection
} else {
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
subscribe(connections.filter(i => i.ip == ip && i.port == port)[0].connection, ip, port)
return connections.filter(i => i.ip == ip && i.port == port)[0].connection
}
}
const createRedisClient = async (port, url) => {
let redisClient = findConnection(url, port)
return redisClient
}
module.exports = { createRedisClient }
几乎可以用了,问题是我不知道如何处理错误
我不确定如何处理错误事件侦听器。如果失败我应该返回一个未定义的,但似乎它没有这样做,
【问题讨论】:
-
你的
findConnection函数在连接存在时不需要调用subscribe。使用完整代码查看我的新答案。
标签: node.js express redis node-redis