You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Quarkus实现AWS ElasticCache Redis的IAM令牌连接?

解决Quarkus连接AWS ElasticCache Redis的令牌生成与凭证配置问题

核心方案

你的超时问题本质是缺少Redis AUTH所需的IAM令牌,Quarkus原生低阶驱动未直接提供凭证注入入口,因此直接基于Lettuce驱动结合AWS SDK实现令牌生成,同时通过STS角色扮演获取临时凭证。

具体实现步骤

1. 添加依赖

确保项目依赖中包含Lettuce Redis驱动和AWS SDK相关模块:

<!-- Quarkus Lettuce Redis客户端 -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-redis-client</artifactId>
</dependency>
<!-- AWS SDK STS模块(用于角色扮演) -->
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>sts</artifactId>
</dependency>
<!-- AWS SDK核心凭证模块 -->
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>credentials</artifactId>
</dependency>
<!-- AWS SDK ElasticCache模块(用于生成令牌) -->
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>elasticache</artifactId>
</dependency>

2. 配置STS角色凭证提供者

创建CDI Bean生成STSAssumeRoleSessionCredentialsProvider,用于获取临时IAM凭证:

import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.STSAssumeRoleSessionCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class AwsStsCredentialsProducer {

    public AwsCredentialsProvider getStsCredentialsProvider() {
        return STSAssumeRoleSessionCredentialsProvider.builder()
                .roleArn("arn:aws:iam::你的AWS账号ID:role/目标角色名")
                .roleSessionName("redis-connect-session")
                .region(Region.of("你的AWS区域(如us-east-1)"))
                .build();
    }
}

3. 生成IAM令牌并配置Lettuce客户端

创建Redis客户端配置Bean,集成令牌生成逻辑,绑定到Lettuce客户端:

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.auth.RedisCredentialsProvider;
import io.lettuce.core.auth.RedisCredentials;
import software.amazon.awssdk.services.elasticache.ElastiCacheClient;
import software.amazon.awssdk.services.elasticache.model.GenerateAuthenticationTokenRequest;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@ApplicationScoped
public class RedisClientProducer {

    @Inject
    AwsCredentialsProvider stsCredentialsProvider;

    public RedisClient createRedisClient() {
        // 替换为你的ElastiCache Redis端点和端口
        String redisEndpoint = "xxx.cache.amazonaws.com";
        int redisPort = 6379;
        String awsRegion = "你的AWS区域";
        String redisUsername = "你的Redis认证用户名(IAM auth模式下必填)";

        // 生成IAM认证令牌
        ElastiCacheClient elasticCacheClient = ElastiCacheClient.builder()
                .credentialsProvider(stsCredentialsProvider)
                .region(Region.of(awsRegion))
                .build();

        GenerateAuthenticationTokenRequest tokenReq = GenerateAuthenticationTokenRequest.builder()
                .username(redisUsername)
                .redisId(redisEndpoint)
                .build();
        String authToken = elasticCacheClient.generateAuthenticationToken(tokenReq);

        // 配置Redis连接地址与凭证
        RedisURI redisUri = RedisURI.builder()
                .host(redisEndpoint)
                .port(redisPort)
                .build();

        RedisCredentialsProvider credProvider = () -> RedisCredentials.just(authToken);

        // 构建带凭证的Lettuce客户端
        return RedisClient.create(redisUri)
                .setOptions(io.lettuce.core.RedisClientOptions.builder()
                        .redisCredentialsProvider(credProvider)
                        .build());
    }
}

4. 修复Redis健康检查

自定义健康检查Bean,使用上述配置的Redis客户端:

import io.smallrye.health.api.HealthCheck;
import io.smallrye.health.api.HealthCheckResponse;
import io.smallrye.health.api.Liveness;
import jakarta.inject.Inject;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;

@Liveness
public class CustomRedisHealthCheck implements HealthCheck {

    @Inject
    RedisClient redisClient;

    @Override
    public HealthCheckResponse call() {
        try (StatefulRedisConnection<String, String> conn = redisClient.connect()) {
            conn.sync().ping();
            return HealthCheckResponse.up("Redis connection health check");
        } catch (Exception e) {
            return HealthCheckResponse.down("Redis connection health check")
                    .withData("reason", e.getMessage());
        }
    }
}

关键注意事项

  • 确保STS角色拥有elasticache:GenerateAuthenticationToken权限,且ElastiCache集群已启用IAM认证。
  • IAM令牌有效期默认15分钟,长期连接需实现自动刷新逻辑(可通过定时任务重新生成令牌,或扩展Lettuce的RedisCredentialsProvider实现自动刷新)。
  • 替换代码中所有占位符为实际环境信息。

内容的提问来源于stack exchange,提问作者bdeweer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:22:37