问题描述
我们有一个在AWS Elastic Beanstalk上具有express的nodeJS服务器,我们正尝试将其与NodeJS的Elasticache(Redis集群化)连接,但收到此错误Redis Client Connection Error ClusterallFailedError: Failed to refresh slots cache.
。由于许多人都面临相同的错误,因此该错误似乎很常见。为了连接到ElastiCache,我们使用了一个名为ioredis
的npm模块。
许多人建议对ElastiCache和Elastic Beanstalk使用相同的VPC和安全组。我们已经在使用相同的VPC,并且在Elastic Beanstalk上,我们正在使用两个安全组,其中一个与ElastiCache的安全组匹配。对于默认的VPC,我们已经为入站和出站规则启用了All Traffic
,但是仍然面临着相同的错误。
为了从NodeJS服务器连接到ElastiCache,我使用以下代码:
const Redis = require("ioredis"); exports.connect = () => { const client = new Redis.Cluster( ["xxxxx.xxxxx.clustercfg.use1.cache.amazonaws.com:6379"],{ slotsRefreshTimeout: 10000,dnsLookup: (address,callback) => callback(null,address),redisOptions: { showFriendlyErrorStack: true,tls: { checkServerIdentity: (/*host,cert*/) => { // skip certificate hostname validation return undefined; },},} ); client.on("ready",() => { console.log("Redis Client Ready"); }); client.on("connect",() => { console.log("Redis Client Connected"); }); client.on("error",(error) => { console.log("Redis Client Connection Error",error); }); client.on("reconnecting",() => { console.log("Redis Client Reconnecting"); }); client.on("end",() => { console.log("Redis Client Connection ended"); }); return client; };
@H_502_15@具有入站和出站规则的默认VPC安全组
Elastic Beanstalk安全组(与默认值相同)
Elastic Beanstalk中的错误信息
版本:
运行在平台版本为
4.15.1
的64位Amazon Linux上的Node.jsNodeJS版本:
12.18.3
ioredis版本:
4.17.3
npm版本:
6.14.6
速成版:
4.17.1
更新:如果我使用ssh并使用redis-cli,则能够从ElasticBeanstalk访问ElastiCache,但无法在运行ElasticBeanstalk的NodeJS上使用
ioredis
来访问它。解决方法
我有一个类似的设置,最终使它起作用,有几点要点:
- Elasticbeanstalk和Elasticache必须位于同一VPC中
- Elasticache的安全组应具有入站规则,以允许来自Elasticbeanstalk的流量
这是要连接的代码:
,import { RedisPubSub } from 'graphql-redis-subscriptions'; import Redis from 'ioredis'; import config from '../../config/env'; const options = { // AWS host will look like this: somecache-dev-ro.k6sjdj.ng.0001.use1.cache.amazonaws.com host: config.redis.host || 'localhost',port: config.redis.port || 6379,retryStrategy: (times: number): number => { // reconnect after return Math.min(times * 50,2000); },}; export const pubsub = new RedisPubSub({ publisher: new Redis(options),subscriber: new Redis(options),});
我正在调试一个类似的问题。要访问 redis,我必须将
tls: {}
添加到 ioredis 选项:{ host: process.env.REDIS_HOST,port: process.env.REDIS_PORT,password: process.env.REDIS_PASSWORD,tls: {} }