Redis缓存为非必要组件时如何在Redis断开时保持Apollo Server正常运行?
Apollo Server Redis缓存断开导致服务宕机解决方案
该问题的核心原因是默认Redis客户端未做错误捕获,且官方BaseRedisCache没有内置容错降级逻辑,Redis相关异常未被捕获会直接终止主进程。可通过以下三层配置解决:
1. 配置Redis客户端容错参数,避免连接异常抛错终止进程
ioredis客户端配置示例
const Redis = require('ioredis'); const redisClient = new Redis({ host: 'redis-server', // 重连策略:最多重试3次,间隔逐步递增 retryStrategy: (times) => { if (times > 3) return null; return Math.min(times * 100, 3000); }, maxRetriesPerRequest: 1, // 单个请求最多重试1次 enableReadyCheck: false, // 关闭就绪检查,未连接成功也不直接抛错 }); // 全局捕获Redis错误,仅打印日志不抛出 redisClient.on('error', (err) => { console.error('Redis连接异常:', err); });
node-redis(v4+)客户端配置示例
const { createClient } = require('redis'); const redisClient = createClient({ url: 'redis://redis-server:6379', socket: { reconnectStrategy: (retries) => { if (retries > 3) return new Error('Redis重试次数超限'); return Math.min(retries * 100, 3000); } } }); redisClient.on('error', (err) => console.error('Redis异常:', err)); // 连接操作单独捕获错误,不影响主进程 redisClient.connect().catch(err => console.error('Redis首次连接失败:', err));
2. 封装容错缓存类,所有缓存操作降级处理
继承官方BaseRedisCache,对所有读写方法添加异常捕获,操作失败直接降级为无缓存逻辑,不向外抛错中断请求:
const { BaseRedisCache } = require('apollo-server-cache-redis'); class FaultTolerantRedisCache extends BaseRedisCache { async get(key) { try { return await super.get(key); } catch (err) { console.error('Redis读取失败:', err); return undefined; // 读取失败视同缓存不存在,走正常查询逻辑 } } async set(key, value, options) { try { return await super.set(key, value, options); } catch (err) { console.error('Redis写入失败:', err); // 写入失败直接忽略,不影响主流程返回 return; } } async delete(key) { try { return await super.delete(key); } catch (err) { console.error('Redis删除失败:', err); return; } } }
3. 替换Apollo Server缓存配置
使用自定义的容错缓存类和配置好的Redis客户端,同时可配置APQ容错策略:
const server = new ApolloServer({ typeDefs, resolvers, cache: new FaultTolerantRedisCache({ client: redisClient, }), dataSources: () => ({ moviesAPI: new MoviesAPI(), }), // 可选:APQ查询缓存失败时允许客户端发送完整查询,避免缓存失效导致请求失败 persistedQueries: { ttl: 3600, allowArbitraryQueries: true, }, });
完成以上配置后,Redis断开或操作异常时只会打印错误日志,所有请求会走无缓存的正常处理逻辑,完全不会导致服务宕机;Redis恢复连接后缓存会自动生效,无需重启服务。
内容的提问来源于stack exchange,提问作者hujinliang
相关产品推荐
相关产品推荐

