尝试从 Docker 中运行的 Spring Boot 应用程序连接到 Redis 时遇到
RedisConnectionFailureException
错误。这是错误消息:
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
设置和观察 环境:
什么有效:
在本地(Docker 外部)运行 Spring Boot 应用程序并在 Docker 中运行 Redis 时,应用程序可以毫无问题地连接到 Redis。
什么不起作用:
当 Spring Boot 应用程序和 Redis 都在 Docker 容器中运行时,我收到连接拒绝错误。
Docker 和应用程序配置 应用程序-docker.properties:
spring.cache.type=redis
spring.redis.host=redis
spring.redis.port=6379
Docker Compose 配置:
应用程序和 Redis 服务都位于同一个 Docker 网络(book-network)上。
添加了 Redis 健康检查和
depends_on
条件,以确保 Redis 在应用程序启动之前完全准备好。
其他详细信息 我已验证以下内容:
网络:Docker Compose 中 app 和 redis 都在同一个网络(book-network),并且可以互相 ping 通。
环境变量:为应用程序容器设置
SPRING_PROFILES_ACTIVE=docker
以确保其使用application-docker.properties
。
docker-compose.yml
networks:
book-network:
driver: bridge
services:
app:
image: elasticsearchbook:latest # Reference to your application image
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # Maps the app's port to the host
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 default port
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 10
networks:
- book-network
restart: always
连接测试:我可以从应用程序容器成功 ping Redis,甚至可以使用 redis-cli 从应用程序容器内部进行连接。 尽管进行了这些检查,当两者都在 Docker 中运行时,Spring Boot 应用程序仍然无法连接到 Redis。
问题
当我的 Spring Boot 应用程序和 Redis 都容器化时,可能会导致两者之间出现连接问题的原因是什么?是否有一些我可能忽略的特定于 Spring Boot 3.3.5 或 Docker 网络的内容?
spring.redis.host
和 spring.redis.port
属性来自 Spring Boot 2.x。它们在 Spring Boot 3 中已重命名为 spring.data.redis.host
和 spring.data.redis.port
。
这样做是为了为
spring.data.*
相关配置属性提供 1 个命名空间。在此之前,存在 spring.data.*
和 spring.redis.*
等事物的混合。因此统一了。
如果您正在遵循 Spring Boot 2 的一些旧教程并使用 Spring Boot 3,这确实会带来挑战。