Java SpringBoot应用无法连接AWS ElastiCache Valkey无服务器缓存
AWS ElastiCache Valkey无服务器版连接Lettuce客户端失败问题排查
问题背景
使用Java SpringBoot应用(JDK 17、SpringBoot 3.2.5)连接AWS ElastiCache Valkey无服务器版(版本8.0),采用Lettuce客户端时,在client.connect()行执行失败,报错无法连接到缓存端点。
代码片段
public void readLettuceCacheAuth() { try { AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest("iam-user-valkey-01", "my-cache", "us-east-1", true); String iamAuthToken = iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); log.info("iamAuthToken: " + iamAuthToken); RedisURI redisURI = RedisURI.builder() .withHost(VALKEY_CACHE_HOST) .withPort(VALKEY_CACHE_PORT) .withSsl(true) .withAuthentication("iam-user-valkey-01", iamAuthToken) .build(); RedisClient client = RedisClient.create(redisURI); log.info("client => " + client); StatefulRedisConnection<String, String> connection = client.connect(); <== exception at this line log.info("connection => " + connection); RedisStringCommands<String, String> syncCommands = connection.sync(); syncCommands.set("key", "value"); String value = syncCommands.get("key"); } catch (Exception e) { log.error("Lettuce error: " + e); } }
报错日志
iamAuthToken: my-cache/?Action=connect&User=iam-user-valkey-01&ResourceType=ServerlessCache&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLXNvdXRoZWFzdC0yIkcwRQIhAO9SJdccIXP2Y2VDj0WxEqdCLQDLMUTbH8IRnbAS11QmAiAOjS client => io.lettuce.core.RedisClient@504021e Lettuce error: io.lettuce.core.RedisConnectionException: Unable to connect to my-cache-fpheum.serverless.apse2.cache.amazonaws.com/<unresolved>:6379
已完成的配置检查
- 缓存与SpringBoot应用处于同一VPC;
- 已更新缓存安全组入站规则,允许Java应用访问6379端口。
问题分析与解决方案
1. 区域参数不匹配(核心错误)
从报错端点的apse2标识可知,缓存位于亚太东南2区(ap-southeast-2),但代码中IAMAuthTokenRequest传入的区域是us-east-1,区域不匹配会导致生成的IAM认证令牌无效,同时干扰DNS解析逻辑。
解决办法:修正区域参数为实际的ap-southeast-2:
IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest("iam-user-valkey-01", "my-cache", "ap-southeast-2", true);
2. VPC内DNS解析故障
报错中的<unresolved>表明应用无法解析缓存端点的私有IP,即使在同一VPC,也需确保DNS配置正常:
- 检查VPC是否启用
enableDnsSupport和enableDnsHostnames(默认启用,若有自定义DNS需调整); - 在应用所在服务器/容器上执行
nslookup my-cache-fpheum.serverless.apse2.cache.amazonaws.com,确认能返回私有IP; - 若使用ECS/EKS,检查任务/ pod的DNS策略是否配置正确,确保使用VPC DNS。
3. SSL连接配置验证
Valkey无服务器版强制要求SSL连接,需确保Lettuce正确处理SSL证书:
- 生产环境:加载AWS官方根证书到应用信任库,或通过Lettuce配置指定SSL上下文:
// 加载AWS CA证书示例(需提前下载证书文件) CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream fis = new FileInputStream("aws-root-ca.pem"); X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(null, null); ks.setCertificateEntry("aws-root-ca", cert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); SslContext sslContext = SslContextBuilder.forClient().trustManager(tmf).build(); RedisURI redisURI = RedisURI.builder() .withHost(VALKEY_CACHE_HOST) .withPort(VALKEY_CACHE_PORT) .withSsl(true) .withSslSocketFactory(sslContext.socketFactory()) .withAuthentication("iam-user-valkey-01", iamAuthToken) .build();
- 测试环境:可临时使用信任所有证书的配置(生产环境禁用):
RedisURI redisURI = RedisURI.builder() .withHost(VALKEY_CACHE_HOST) .withPort(VALKEY_CACHE_PORT) .withSsl(true) .withSslSocketFactory(SslContextBuilder.forClient().trustManager(TrustAllTrustManager.INSTANCE).build().socketFactory()) .withAuthentication("iam-user-valkey-01", iamAuthToken) .build();
4. IAM权限验证
确保IAM用户iam-user-valkey-01拥有elasticache:Connect权限,且资源ARN匹配:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "elasticache:Connect", "Resource": "arn:aws:elasticache:ap-southeast-2:你的AWS账号ID:serverlesscache:my-cache" } ] }
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

