最近,我很难从 Amazon ECS 中运行的 Next.js 应用程序连接到 Amazon MemoryDB for Redis(集群)!
起初,我以为我的VPC和/或安全组配置错误,但我仔细检查了一下,Redis集群和Next应用程序都在同一个VPC上,并且安全组允许它们之间的连接;我还检查了 VPC 是否启用了 DNS 解析,确实如此!
我终于设法让它运行起来,所以我在这里发布我的答案,以防有人发现自己处于同样的情况。
我发现问题在于我尝试连接 Redis 集群的方式;我正在使用
ioredis
,我的代码是这样的:
import Redis from "ioredis";
const host = process.env.REDIS_HOST;
const port = +process.env.REDIS_PORT!;
export const redis = new Redis({ host, port });
该设置导致了
Timeout
错误!
经过一番调查,我发现我应该使用
Cluster
中的 ioredis
构造函数,而不是默认的 Redis
构造函数!但我仍然收到错误ClusterAllFailedError: Failed to refresh slots cache
。
最后经过进一步的调查和测试,我找到了连接Redis集群的正确方法如下:
import { Cluster } from "ioredis";
const host = process.env.REDIS_HOST;
const port = +process.env.REDIS_PORT!;
export const redis = new Cluster([{ host, port }], {
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
tls: {},
},
});
其中
REDIS_HOST
是 AWS 上 Redis 集群的端点,REDIS_PORT
是集群端口!
希望能帮助您节省一些时间,因为我在任何地方都找不到此设置的记录!
我也遇到了和你一样的问题。确实需要开启一个ssl加密传输。成功链接的代码如下:
@Configuration
public class RedisConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.max-redirects}")
private int maxRedirects;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisClusterConfiguration configuration = new RedisClusterConfiguration();
Set<RedisNode> redisNodes = new HashSet<>();
for (String node : clusterNodes.split(",")) {
String[] parts = node.split(":");
redisNodes.add(new RedisNode(parts[0], Integer.parseInt(parts[1])));
}
configuration.setClusterNodes(redisNodes);
configuration.setMaxRedirects(maxRedirects);
// 配置SSL
LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration.builder();
SslOptions sslOptions = SslOptions.builder().jdkSslProvider().build();
ClientOptions clientOptions = ClientOptions.builder().sslOptions(sslOptions).build();
//disablePeerVerification 关闭证书校验
lettuceClientConfigurationBuilder.clientOptions(clientOptions).useSsl().disablePeerVerification();
return new LettuceConnectionFactory(configuration,lettuceClientConfigurationBuilder.build());
}
@Bean
public StringRedisTemplate stringRedisTemplate() {
return new StringRedisTemplate(redisConnectionFactory());
}
}
下面是我的配置文件:
server:
port: 8889
servlet:
context-path: /redis-demo
spring:
redis:
cluster:
nodes: myredis-0001-001.myredis.c7uerl.memorydb.us-west-1.amazonaws.com:6379,myredis-0001-002.myredis.c7uerl.memorydb.us-west-1.amazonaws.com:6379
max-redirects: 3
ssl:
enable: true
目前Amazon Memory Redis并没有直接提供访问的用户名和密码,后续应该可以调用API来创建