首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Node.js redis@4升级: SocketClosedUnexpectedlyError:套接字意外关闭

Node.js redis@4升级: SocketClosedUnexpectedlyError:套接字意外关闭
EN

Stack Overflow用户
提问于 2022-09-21 23:26:32
回答 1查看 85关注 0票数 0

我有一些遗留代码,正在从Node.js redis库的第3版升级到Node.js redis库的第4版。代码的基本形状如下所示

代码语言:javascript
运行
复制
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退出时使用的是非零状态代码

代码语言:javascript
运行
复制
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错误而失败。

EN

回答 1

Stack Overflow用户

发布于 2022-11-25 19:21:24

到目前为止,我发现在没有任何请求的情况下,经过一段时间(keepAlive默认值为5分钟),Redis客户端将关闭并抛出一个错误事件,但是如果您不处理该事件,它将使您的应用程序崩溃。我的解决办法是:

代码语言:javascript
运行
复制
/* 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,
}

总之..。在您的情况下,尝试处理错误事件。

代码语言:javascript
运行
复制
client.on('error', err => logger.error(`Redis Error: ${err}`))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73807874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档