AWS EC2上Spring Boot应用无法连接Redis:RedisConnectionException排查
问题背景
我在AWS上部署了EC2实例,需求是在名为worker1的EC2实例中的Spring Boot项目内访问Redis实例(原文表述存在矛盾:标注Redis位于worker1,又提及名为worker5的EC2实例)。针对worker1,我编写了包含Redis服务的Docker Compose配置:
version: "3.5" services: redis: hostname: redis image: 'redis' ports: - "6379:6379" deploy: replicas: 1 placement: constraints: - node.labels.redis == redis logging: options: labels: "serviceName,instanceId" labels: serviceName: "redis" instanceId: "redis" networks: - messaging-overlay-network
Spring Boot项目的application.yml配置如下:
spring: cache: redis: host: redis port: 6379 time-to-live: 0 type: redis
同时编写了Redis配置类:
@Configuration @ConfigurationProperties(prefix = "spring.cache.redis") @Setter public class RedisConfig { private String host; @Bean @Primary public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory(RedisConfiguration defaultRedisConfig) { LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .useSsl().and() .commandTimeout(Duration.ofMillis(60000)).build(); return new LettuceConnectionFactory(defaultRedisConfig, clientConfig); } @Bean public RedisConfiguration defaultRedisConfig() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); config.setHostName(host); return config; } }
已在安全组中开放对应端口,但使用Redis时仍报错:Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to redis:6379
问题排查与解决
1. Docker网络连通性问题
你的Redis服务挂载在messaging-overlay-network自定义网络中,如果Spring Boot应用没有加入同一个Docker网络,就无法通过redis主机名解析到容器。
- 检查Spring Boot应用的Docker部署配置:如果是用Docker Compose部署,要在服务的
networks字段中添加messaging-overlay-network;如果是单独运行的容器,执行docker network connect messaging-overlay-network <spring-boot-container-name>将其加入目标网络。
2. Redis容器节点约束不满足
Docker Compose中设置了placement.constraints: node.labels.redis == redis,这要求Redis容器必须部署在带有redis=redis标签的Docker节点上。如果worker1节点没有该标签,Redis容器不会启动在worker1上,自然无法连接。
- 执行
docker node ls查看节点标签,确认worker1是否有redis=redis标签;如果没有,执行docker node update --label-add redis=redis worker1添加标签,然后重新部署Redis服务。
3. SSL配置不兼容
Spring Boot配置类中强制开启了SSL(.useSsl()),但默认的Redis镜像未启用SSL,这会导致SSL握手失败,表现为连接超时或失败。
- 如果无需SSL,直接删除配置类中的
.useSsl()代码;如果需要SSL,需修改Redis容器配置,启用SSL并配置对应证书,同时确保Spring Boot端的证书配置与Redis匹配。
4. 主机名解析场景不匹配
如果Spring Boot应用直接运行在worker1的EC2主机上(而非Docker容器内),redis这个主机名无法被EC2主机解析(Docker容器主机名仅在容器网络内有效)。
- 这种情况下,将
application.yml中的spring.cache.redis.host改为localhost或worker1的私有IP即可,因为Redis容器已将6379端口映射到EC2主机。
内容的提问来源于stack exchange,提问作者Bertug

