Node.js 无法从ElasticBeanstalk上的NodeJS服务器连接ElastiCache
我们在AWS Elastic Beanstalk上有一个带有express的nodeJS服务器,我们正在尝试从nodeJS将其与Elasticache(Redis clustered)连接,但收到此错误Node.js 无法从ElasticBeanstalk上的NodeJS服务器连接ElastiCache,node.js,amazon-web-services,redis,amazon-elastic-beanstalk,amazon-elasticache,Node.js,Amazon Web Services,Redis,Amazon Elastic Beanstalk,Amazon Elasticache,我们在AWS Elastic Beanstalk上有一个带有express的nodeJS服务器,我们正在尝试从nodeJS将其与Elasticache(Redis clustered)连接,但收到此错误Redis客户端连接错误ClusterAllFailedError:刷新插槽缓存失败。。这个错误似乎很常见,因为很多人都面临相同的错误。为了连接到ElastiCache,我们使用了一个名为ioredis的npm模块 很多人建议对ElastiCache和ElasticBeanstalk使用相同的VP
Redis客户端连接错误ClusterAllFailedError:刷新插槽缓存失败。
。这个错误似乎很常见,因为很多人都面临相同的错误。为了连接到ElastiCache,我们使用了一个名为ioredis
的npm模块
很多人建议对ElastiCache和ElasticBeanstalk使用相同的VPC和安全组。我们已经在使用相同的VPC,在Elastic Beanstalk上,我们使用了两个安全组,其中一个与ElastiCache的安全组匹配。对于默认VPC,我们为入站和出站规则启用了所有流量
,但我们仍然面临相同的错误
为了从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;
};
ElastiCache配置
具有入站和出站规则的默认VPC安全组
弹性豆茎安全组(与默认值相同)
弹性豆茎的错误信息
版本:
Node.js在64位Amazon Linux上运行,平台版本为4.15.1
NodeJS版本: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),
});
我有一个类似的设置,并最终使其工作,有几个关键点:
- 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: {}
}
我正在调试一个类似的问题。要访问redis,我必须将
tls:{}
添加到ioredis选项中:
{
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
tls: {}
}
如果您使用ssh连接到EB实例中,并且仅使用
redis cli
手动连接,那么它也无法工作?此检查将有助于验证连接问题是否是实例范围内的问题,或者仅限于您的应用程序。@Marcin我刚刚检查过,我可以通过对EB实例执行ssh来访问ElastiCache。因此,至少现在您知道安全组和其他网络设置是可以的。所以原因一定与您的应用程序有关。@Marcin是的,我认为如果您ssh到EB实例中,并且只使用redis cli
手动连接,ioredis
也不起作用,那么ioredis有问题吗?此检查将有助于验证连接问题是否是实例范围内的问题,或者仅限于您的应用程序。@Marcin我刚刚检查过,我可以通过对EB实例执行ssh来访问ElastiCache。因此,至少现在您知道安全组和其他网络设置是可以的。所以原因一定与您的应用程序有关。@Marcin是的,我认为ioredis有问题