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

Node.js应用连接Redis时出现“Socket already opened”与“The client is closed”错误的排查咨询

Hey there, let's break down what's causing your Redis connection issues and fix them step by step!

Why You're Seeing These Errors

  1. "Socket already opened": You're calling await client.connect() every time your route runs, but you've exported a single Redis client instance from redisClient.ts. Once that client connects on the first request, trying to call connect() again on the same instance throws this error—since the socket is already open.
  2. "The client is closed": If you skip connect(), the client starts in a closed state by default, so it can't send any commands to Redis.

Fix 1: Connect Once When Initializing the Client

The cleanest approach is to connect your Redis client once when the app starts, not on every request. Update your redisClient.ts like this:

import redis = require('redis');
const client = redis.createClient({url: 'myRedisURL'});

// Handle connection errors to avoid uncaught exceptions
client.on('error', (err) => console.error('Redis Client Error:', err));

// Connect immediately when the module loads
(async () => {
  try {
    await client.connect();
    console.log('Successfully connected to Redis');
  } catch (err) {
    console.error('Failed to connect to Redis:', err);
  }
})();

export default client;

Then in myRoute.ts, remove the await client.connect() line entirely—you can use the client directly:

import client from './redisClient';

// ... your route logic
let redisValue: string | null;
redisValue = await client.get(key);

if (!redisValue) {
  redisValue = await some_external_api_call(key);
  // Fix: Use redisValue instead of the undefined "value" variable
  await client.set(key, redisValue, {EX: 3600 * 24});
}

Fix 2: Check Connection State Before Using (For Dynamic Scenarios)

If you need to handle cases where the client might disconnect and reconnect later, add a check for the client's ready state before sending commands:

import client from './redisClient';

// ... your route logic
let redisValue: string | null;

try {
  // Only connect if the client isn't already ready
  if (!client.isReady) {
    await client.connect();
  }

  redisValue = await client.get(key);
  if (!redisValue) {
    redisValue = await some_external_api_call(key);
    await client.set(key, redisValue, {EX: 3600 * 24});
  }
} catch (err) {
  console.error('Redis operation failed:', err);
  // Add error handling for your route here (e.g., return a 500 response)
}

Extra Tips to Avoid Future Issues

  • Variable Typo: Your original code uses value in client.set() but defines redisValue—fix that to avoid undefined variable errors.
  • Single Instance: Always use a single Redis client instance across your app. Creating a new client per request will exhaust your Redis connection pool quickly.
  • Graceful Shutdown: Add code to close the Redis connection when your app exits:
    process.on('SIGINT', async () => {
      await client.quit();
      process.exit(0);
    });
    

内容的提问来源于stack exchange,提问作者Edward Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:52:45