Redis ClientClosedError报错解决:缓存Github仓库数据时客户端已关闭
修复Redis ClientClosedError: The client is closed错误
问题背景
我正在学习Redis,尝试获取Github仓库数据并将其存入Redis缓存,但在使用Redis时遇到如下错误:
- 报错位置:
redis-and-fetch/node_modules/@redis/client/dist/lib/client/index.js:409 - 报错信息:
ClientClosedError: The client is closed
原代码
import express from "express"; import Redis from "redis"; import fetch from "node-fetch"; const PORT = process.env.PORT || 5000; const REDIS_PORT = process.env.REDIS_PORT || "6379"; const client = Redis.createClient(REDIS_PORT); const app = express(); // Set response function setResponse(username, repos) { return `<h2>${username} has ${repos} Github repos</h2>`; } // Make request to Github for data async function getRepos(req, res, next) { try { console.log("Fetching Data..."); const { username } = req.params; const response = await fetch(`https://api.github.com/users/${username}`); const data = await response.json(); const repos = data.public_repos; // Set data to Redis // await client.connect(); client.setEx(username, 3600, repos); res.send(setResponse(username, repos)); } catch (e) { console.log(e); res.status(500); } } app.get("/repos/:username", getRepos); app.listen(5000, () => { console.log(`App listening on port ${PORT}`); });
修复方案
核心问题
Redis v4及以上版本的客户端必须显式调用connect方法建立连接,你注释掉了await client.connect();,导致客户端始终处于关闭状态,执行setEx命令时触发ClientClosedError。
具体修复步骤
- 恢复并正确调用connect方法:在使用客户端执行命令前,确保已经完成连接。推荐在启动Express服务前完成Redis连接,避免每次请求都重复连接。
- 添加错误监听:监听Redis客户端的
error事件,及时排查连接问题。 - 处理连接状态:确保客户端连接成功后再处理HTTP请求。
修改后的完整代码
import express from "express"; import Redis from "redis"; import fetch from "node-fetch"; const PORT = process.env.PORT || 5000; const REDIS_PORT = process.env.REDIS_PORT || "6379"; // 创建Redis客户端,v4+版本推荐传入配置对象而非直接传端口 const client = Redis.createClient({ port: REDIS_PORT }); // 监听Redis连接错误 client.on('error', (err) => { console.error('Redis Client Error:', err); }); const app = express(); // Set response function setResponse(username, repos) { return `<h2>${username} has ${repos} Github repos</h2>`; } // Make request to Github for data async function getRepos(req, res, next) { try { console.log("Fetching Data..."); const { username } = req.params; const response = await fetch(`https://api.github.com/users/${username}`); if (!response.ok) { throw new Error(`Github API request failed: ${response.status}`); } const data = await response.json(); const repos = data.public_repos; // 执行Redis命令(此时客户端已连接) await client.setEx(username, 3600, repos); res.send(setResponse(username, repos)); } catch (e) { console.log(e); res.status(500).send('Internal Server Error'); } } app.get("/repos/:username", getRepos); // 先连接Redis,再启动Express服务 async function startServer() { try { await client.connect(); console.log('Connected to Redis'); app.listen(PORT, () => { console.log(`App listening on port ${PORT}`); }); } catch (err) { console.error('Failed to connect to Redis:', err); process.exit(1); } } startServer();
额外说明
- Redis v4版本不再支持自动连接,必须手动调用
connect()方法。 - 使用
await确保连接完成后再启动服务,避免请求到达时客户端未就绪。 - 添加了Github API响应状态检查,增强错误处理逻辑。
内容的提问来源于stack exchange,提问作者Irakli
相关产品推荐
相关产品推荐

