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

Docker中Spring Boot应用无法连接Redis容器(连接被拒绝)

问题:Docker容器化Spring Boot应用连接Redis失败

错误信息

ERROR 1 --- [ElasticSearch_books] [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis] with root cause
java.net.ConnectException: Connection refused

环境与观察

  • Spring Boot版本:3.3.5
  • Redis和Spring Boot应用均已容器化运行

场景对比

  • 正常场景:Spring Boot应用在本地(Docker外)运行,可正常连接Docker中的Redis
  • 异常场景:两者都在Docker容器中运行时,出现连接拒绝错误

配置详情

application-docker.properties

spring.cache.type=redis
spring.redis.host=redis
spring.redis.port=6379

Docker Compose配置

应用与Redis处于同一自定义网络book-network,已配置Redis健康检查和depends_on依赖条件,确保Redis就绪后再启动应用。完整配置如下:

networks:
  book-network:
    driver: bridge

services:
  app:
    image: elasticsearchbook:latest  # 应用镜像
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"  # 端口映射到宿主机
    depends_on:
      elasticsearch:
        condition: service_healthy
      redis:
        condition: service_healthy
      prometheus:
        condition: service_healthy
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - SPRING_DATA_ELASTICSEARCH_HOST=elasticsearch
      - SPRING_DATA_ELASTICSEARCH_PORT=9200
      - SPRING_REDIS_HOST=redis
      - SPRING_REDIS_PORT=6379
    networks:
      - book-network
    restart: always
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"  # Redis默认端口映射
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - book-network
    restart: always

已验证内容

  • 网络连通性:应用容器可ping通Redis容器,且在应用容器内用redis-cli -h redis能正常连接Redis
  • 环境变量:已设置SPRING_PROFILES_ACTIVE=docker,确认应用加载了application-docker.properties

尽管完成以上检查,容器化的Spring Boot应用仍无法连接Redis,求排查方向,是否有Spring Boot 3.3.5或Docker网络相关的细节被遗漏?


排查思路与解决方案

1. 检查Spring Boot配置优先级冲突

你同时在application-docker.properties和Docker环境变量里配置了Redis连接参数,Spring Boot 3.x的配置优先级中,环境变量优先级高于properties文件。虽然两者配置内容一致,但如果构建镜像时不小心打包了其他环境的配置(比如application.properties里写了spring.redis.host=localhost),或者环境变量未正确覆盖,可能导致应用实际使用错误的连接地址。

可以进入应用容器,执行以下命令查看Spring Boot实际加载的配置:

java -jar your-app.jar --debug | grep redis

或者在应用启动日志里搜索RedisProperties相关内容,确认最终生效的host和port是否正确。

2. 检查Redis绑定地址

默认情况下,部分Redis镜像的配置可能绑定127.0.0.1,这会限制仅容器内部可访问。虽然你已经能从应用容器用redis-cli连接,但仍建议确认Redis的监听地址:

进入Redis容器,执行命令:

redis-cli CONFIG GET bind

如果返回结果是127.0.0.1,需要修改Redis配置,让它绑定0.0.0.0以允许外部容器访问。可以在docker-compose的redis服务中添加启动命令:

redis:
  image: redis:alpine
  command: redis-server --bind 0.0.0.0
  # 其余配置保持不变

3. 切换Redis客户端测试

Spring Boot 3.3.x默认使用Lettuce作为Redis客户端,可能存在初始化时的网络延迟或DNS解析问题。可以尝试切换为Jedis客户端,排查是否为客户端兼容性问题:

在pom.xml(Maven)中添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

4. 优化容器启动顺序的健康检查

虽然配置了depends_on的service_healthy,但Redis的ping检查通过时,可能服务还未完全就绪(比如加载数据或完成初始化)。可以修改健康检查命令为更严格的测试:

redis:
  healthcheck:
    test: [ "CMD", "redis-cli", "info", "server" ]
    interval: 10s
    timeout: 5s
    retries: 10

或者在应用的启动脚本中添加延迟,给Redis更多初始化时间:

sleep 10 && java -jar your-app.jar

5. 检查Docker网络DNS解析

虽然能ping通Redis,但Spring Boot应用启动时可能出现DNS解析延迟或缓存问题。可以在应用容器中手动测试DNS解析:

nslookup redis

如果解析正常,可尝试在应用的JVM参数中禁用DNS缓存,确保每次连接都重新解析地址:

-Dsun.net.inetaddr.ttl=0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:48:24