如何处理 express 中的 redis 连接错误?
How to handle a redis connection error in express?
我有一个 express 数据库,它通过接收来自客户端的连接 ip 连接到多个 redis 服务器。
如果redis 数据库存在,则可以正常工作。我面临的问题是,如果 ip 不存在,我将收到
Error: Error: Redis connection to xxxx failed - connect ECONNREFUSED
xxx
这完全可以理解,但问题是我的连接对象仍然被定义。而且我真的不知道如何将这个对象识别为失败的连接。
我可能唯一的提示可能在 connection._events.error
变量中,但它 returns a [Function]
这是我的代码
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) {
//this is supposed to handle the error, but i dont know how to make the "undefined" value available for the createRedisClient function. Since this seems to be delayed
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) {
return connection[0].connection
} else {
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
let pushedConnection = connections.filter(i => i.ip == ip && i.port == port)[0].connection
subscribe(pushedConnection, ip, port)
return pushedConnection
}
}
const createRedisClient = async (port, url) => {
let redisClient = findConnection(url, port)
console.log(redisClient._events.error) //[Function]
return redisClient // this is always a connection object, even if the connection is faulty
}
module.exports = { createRedisClient }
然后 findConnection
returns 连接状态未知,因为 node-redis 是 asynchronous, it uses callbacks。一种解决方案是承诺您的 subscribe
函数,如下所示:
const subscribe = (redisClient, url, port) => new Promise((resolve, reject) => {
redisClient.on('error', function (err) {
console.log(err)
killRedis(redisClient, url, port)
reject(err)
});
redisClient.on('connect', function () {
console.log('Connected to Redis');
resolve(redisClient)
});
})
然后,在 findConnection
中,您只需使用 try-catch
块处理可能的拒绝。请注意,它已被标记为 async
:
findConnection = async (ip, port) => {
let connection = connections.filter(i => i.ip == ip && i.port == port)
if (connection && connection.length > 0) {
return connection[0].connection
} else {
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
let pushedConnection = connections.filter(i => i.ip == ip && i.port == port)[0].connection
try {
const client = await subscribe(pushedConnection, ip, port)
return client
} catch (error) {
return undefined // not sure what you want to do with rejections
}
}
然后,最后(也是async
):
const createRedisClient = async (port, url) => {
let redisClient = await findConnection(url, port)
console.log(redisClient)
return redisClient // this is undefined if there was an error connecting
}
而不是 async-await
,您始终可以使用 then-catch
等。另外,我相信 error
回调将在每个错误时调用。也就是说,在连接成功的情况下,如果稍后遇到任何 redis 错误,仍然会调用 killRedis
。如果是故意的,好吧。否则,您可能需要重构您的逻辑,以便仅在成功建立连接后才注册连接。
我有一个 express 数据库,它通过接收来自客户端的连接 ip 连接到多个 redis 服务器。
如果redis 数据库存在,则可以正常工作。我面临的问题是,如果 ip 不存在,我将收到
Error: Error: Redis connection to xxxx failed - connect ECONNREFUSED xxx
这完全可以理解,但问题是我的连接对象仍然被定义。而且我真的不知道如何将这个对象识别为失败的连接。
我可能唯一的提示可能在 connection._events.error
变量中,但它 returns a [Function]
这是我的代码
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) {
//this is supposed to handle the error, but i dont know how to make the "undefined" value available for the createRedisClient function. Since this seems to be delayed
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) {
return connection[0].connection
} else {
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
let pushedConnection = connections.filter(i => i.ip == ip && i.port == port)[0].connection
subscribe(pushedConnection, ip, port)
return pushedConnection
}
}
const createRedisClient = async (port, url) => {
let redisClient = findConnection(url, port)
console.log(redisClient._events.error) //[Function]
return redisClient // this is always a connection object, even if the connection is faulty
}
module.exports = { createRedisClient }
然后 findConnection
returns 连接状态未知,因为 node-redis 是 asynchronous, it uses callbacks。一种解决方案是承诺您的 subscribe
函数,如下所示:
const subscribe = (redisClient, url, port) => new Promise((resolve, reject) => {
redisClient.on('error', function (err) {
console.log(err)
killRedis(redisClient, url, port)
reject(err)
});
redisClient.on('connect', function () {
console.log('Connected to Redis');
resolve(redisClient)
});
})
然后,在 findConnection
中,您只需使用 try-catch
块处理可能的拒绝。请注意,它已被标记为 async
:
findConnection = async (ip, port) => {
let connection = connections.filter(i => i.ip == ip && i.port == port)
if (connection && connection.length > 0) {
return connection[0].connection
} else {
connections.push({
ip: ip,
port: port,
connection: require('redis').createClient(port, ip, {
no_ready_check: true,
db: 1
})
})
let pushedConnection = connections.filter(i => i.ip == ip && i.port == port)[0].connection
try {
const client = await subscribe(pushedConnection, ip, port)
return client
} catch (error) {
return undefined // not sure what you want to do with rejections
}
}
然后,最后(也是async
):
const createRedisClient = async (port, url) => {
let redisClient = await findConnection(url, port)
console.log(redisClient)
return redisClient // this is undefined if there was an error connecting
}
而不是 async-await
,您始终可以使用 then-catch
等。另外,我相信 error
回调将在每个错误时调用。也就是说,在连接成功的情况下,如果稍后遇到任何 redis 错误,仍然会调用 killRedis
。如果是故意的,好吧。否则,您可能需要重构您的逻辑,以便仅在成功建立连接后才注册连接。