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); }
错误截图

错误原因
redisClient未建立连接:代码中仅对subscriber调用了connect()完成连接,但用于执行哈希表写入操作的redisClient没有执行连接操作,始终处于关闭状态,调用hSet时自然触发报错。- 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
相关产品推荐
相关产品推荐

