You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境下Node.js中Redis抛出ClientClosedError错误的原因

Redis订阅端「The client is closed」错误原因及解决

问题背景

Docker环境部署Redis,后端基于Node.js、数据库用PostgreSQL、前端是React。业务流程为:前端传入索引值,后端计算对应斐波那契数返回;服务端将该索引值发布至Redis,但Redis订阅端每次接收消息时,都会抛出「The client is closed」错误。

相关Redis代码

const redis = require("redis");
const keys = require("./keys");

const redisClient = redis.createClient({
  // host: keys,
  // port: keys.redisPort,
  //  retry_strategy: () => 1000, if connection is lost, retry every sec
});

const subscriber = redisClient.duplicate();

const connectRedis = () => {
  subscriber
    .connect()
    .then(() => console.log("redis worker connected"))
    .catch((err) => console.log("err redis connection", err));
};

connectRedis();

subscriber.subscribe("insert", async (message) => {
  console.log({ message });
  const val = fib(parseInt(message));
  redisClient.hSet("values", message, JSON.stringify(val));
});

function fib(index) {
  if (!index) return;
  if (index < 2) return 1;

  return fib(index - 1) + fib(index - 2);
}

错误截图

Redis错误:The client is closed

错误原因

  1. redisClient未建立连接:代码中仅对subscriber调用了connect()完成连接,但用于执行哈希表写入操作的redisClient没有执行连接操作,始终处于关闭状态,调用hSet时自然触发报错。
  2. Redis v4+版本特性:Redis官方Node.js客户端v4及以上版本中,createClient()创建实例后不会自动连接Redis服务,必须显式调用connect()才能建立有效连接。

解决方案

给redisClient添加连接逻辑,确保它成功连接到Redis后再进行操作,修改后的代码示例如下:

const redis = require("redis");
const keys = require("./keys");

const redisClient = redis.createClient({
  // 补充Redis连接配置,适配你的Docker环境
  host: keys.redisHost,
  port: keys.redisPort,
  retry_strategy: () => 1000 // 连接断开时每秒重试一次
});

const subscriber = redisClient.duplicate();

// 统一处理Redis客户端连接
const connectRedisClients = async () => {
  try {
    await redisClient.connect();
    console.log("redis client connected");
    await subscriber.connect();
    console.log("redis subscriber connected");
  } catch (err) {
    console.log("Redis连接错误", err);
    // 连接失败自动重试
    setTimeout(connectRedisClients, 1000);
  }
};

connectRedisClients();

subscriber.subscribe("insert", async (message) => {
  console.log({ message });
  const val = fib(parseInt(message));
  // 确保客户端就绪后再执行操作
  if (redisClient.isReady) {
    await redisClient.hSet("values", message, JSON.stringify(val));
  }
});

function fib(index) {
  if (!index) return;
  if (index < 2) return 1;

  return fib(index - 1) + fib(index - 2);
}

额外说明

  • 务必补充redisClient的连接配置(host和port),匹配Docker中Redis服务的地址和端口。
  • 添加isReady判断可以避免连接未就绪时执行操作的报错,提升代码健壮性。

内容的提问来源于stack exchange,提问作者Sandeep M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:05:11