Node.js通过Docker Compose连接Redis失败,报错ECONNREFUSED
解决Docker Compose中Node.js连接Redis超时问题
问题分析
你的代码和配置存在几个关键问题,导致Redis连接失败:
- 语法错误:
on('error', err => ...)未指定所属对象,应为client.on(...),该错误会导致Redis客户端初始化异常, fallback到默认的localhost:6379连接。 - 异步处理不当:直接在
createClient后调用client.set,此时Redis连接可能尚未建立,触发连接错误。 - 响应重复发送:
app.get中同时调用res.send和res.json,会导致HTTP响应头重复设置的错误,干扰正常逻辑。 - 缺少ES模块配置:使用
import语法需要在package.json中添加"type": "module",否则Node.js会将文件视为CommonJS模块,引发语法错误。
修复后的app.js代码
import express from "express"; import { createClient } from 'redis'; const app = express(); const port = process.env.PORT || 3000; // 修正拼写错误:API_PRIFEX -> API_PREFIX const apiPrefix = process.env.API_PREFIX; // 初始化Redis客户端 const client = createClient({ url: 'redis://redis:6379' }); // 绑定错误监听到client对象 client.on('error', err => console.log('Redis Client Error', err)); // 异步初始化流程,确保连接成功后启动服务 async function init() { try { await client.connect(); console.log('Connected to Redis'); // 仅当visits键不存在时初始化值 const existingVisits = await client.get('visits'); if (!existingVisits) { await client.set('visits', 0); } // 使用Promise API处理Redis操作,替代回调 app.get("/", async (req, res) => { try { const visits = await client.get('visits'); const newVisits = parseInt(visits) + 1; await client.set('visits', newVisits); res.send(`Number of visits is ${newVisits}`); } catch (err) { res.status(500).send('Failed to fetch visits'); console.error(err); } }); app.listen(port, () => { console.log(`service is up and running on Port:${port}`); }); } catch (err) { console.error('Failed to connect to Redis', err); process.exit(1); } } init();
Docker Compose配置优化
基础配置无问题,但可以添加健康检查和依赖条件,确保Node服务在Redis就绪后启动:
version: "3" services: redis: image: "redis" ports: - "6379:6379" # 添加健康检查,验证Redis服务可用性 healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 30s retries: 5 node-app: build: . ports: - "4001:3000" # 等待Redis健康检查通过后再启动 depends_on: redis: condition: service_healthy
额外注意事项
- 在项目根目录的
package.json中添加"type": "module",确保Node.js识别ES模块语法:
{ "type": "module", "dependencies": { "express": "^4.18.2", "redis": "^4.6.7" } }
- 构建镜像时,确保
package.json和package-lock.json被复制到镜像中,安装正确依赖。
内容的提问来源于stack exchange,提问作者Umaiz khan
相关产品推荐
相关产品推荐

