我有一些遗留代码,正在从Node.js redis库的第3版升级到Node.js redis库的第4版。代码的基本形状如下所示
var redis = require('redis')
var client = redis.createClient({
port: '6379',
host: process.env.REDIS_HOST,
legacyMode: true
})
client.connect()
client.flushall(function (err, reply) {
client.hkeys('hash key', function (err, replies) {
console.log("key set done")
client.quit()
})
})
console.log("main done")
当我使用redis@4.3.1运行这段代码时,我得到以下错误,node.js退出时使用的是非零状态代码
main done
key set done
events.js:292
throw er; // Unhandled 'error' event
^
SocketClosedUnexpectedlyError: Socket closed unexpectedly
at Socket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/@redis/client/dist/lib/client/socket.js:182:118)
at Object.onceWrapper (events.js:422:26)
at Socket.emit (events.js:315:20)
at TCP.<anonymous> (net.js:673:12)
Emitted 'error' event on Commander instance at:
at RedisSocket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/@redis/client/dist/lib/client/index.js:350:14)
at RedisSocket.emit (events.js:315:20)
at RedisSocket._RedisSocket_onSocketError (/Users/astorm/Documents/redis4/node_modules/@redis/client/dist/lib/client/socket.js:205:10)
at Socket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/@redis/client/dist/lib/client/socket.js:182:107)
at Object.onceWrapper (events.js:422:26)
at Socket.emit (events.js:315:20)
at TCP.<anonymous> (net.js:673:12)
在redis@3.1.2中,它没有问题地运行(减去client.connect()
)。
我已经能够通过用client.quit()
替换client.disconnect()
来解决这个问题,但是实际的代码比上面的例子要复杂一些,我宁愿使用client.quit
的优雅关闭,也不愿使用client.disconnect()
的更严厉的“立即关闭IT”。
有人知道这里可能有什么问题吗?为什么redis@4由于SocketClosedUnexpectedlyError: Socket closed unexpectedly
错误而失败。
发布于 2022-11-25 19:21:24
到目前为止,我发现在没有任何请求的情况下,经过一段时间(keepAlive默认值为5分钟),Redis客户端将关闭并抛出一个错误事件,但是如果您不处理该事件,它将使您的应用程序崩溃。我的解决办法是:
/* eslint-disable no-inline-comments */
import type { RedisClientType } from 'redis'
import { createClient } from 'redis'
import { config } from '@app/config'
import { logger } from '@app/utils/logger'
let redisClient: RedisClientType
let isReady: boolean
const cacheOptions = {
url: config.redis.tlsFlag ? config.redis.urlTls : config.redis.url,
}
if (config.redis.tlsFlag) {
Object.assign(cacheOptions, {
socket: {
// keepAlive: 300, // 5 minutes DEFAULT
tls: false,
},
})
}
async function getCache(): Promise<RedisClientType> {
if (!isReady) {
redisClient = createClient({
...cacheOptions,
})
redisClient.on('error', err => logger.error(`Redis Error: ${err}`))
redisClient.on('connect', () => logger.info('Redis connected'))
redisClient.on('reconnecting', () => logger.info('Redis reconnecting'))
redisClient.on('ready', () => {
isReady = true
logger.info('Redis ready!')
})
await redisClient.connect()
}
return redisClient
}
getCache().then(connection => {
redisClient = connection
}).catch(err => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
logger.error({ err }, 'Failed to connect to Redis')
})
export {
getCache,
}
总之..。在您的情况下,尝试处理错误事件。
client.on('error', err => logger.error(`Redis Error: ${err}`))
https://stackoverflow.com/questions/73807874
复制相似问题