Docker Compose部署Spring Boot+RabbitMQ时连接被拒绝问题排查
原因分析
核心问题是Spring Boot应用未读取到Docker Compose注入的环境变量,仍使用application.yml中硬编码的localhost配置。
虽然Spring Boot理论上支持环境变量覆盖jar包内的application.yml配置,但你的场景中环境变量未生效,大概率是因为:
application.yml直接硬编码了spring.rabbitmq.host=localhost,未通过占位符预留环境变量替换入口,导致环境变量无法覆盖硬编码值;- 少数情况是应用自定义了配置加载逻辑,降低了环境变量的优先级。
解决方法
方法一:修改application.yml使用占位符(推荐)
将application.yml中的RabbitMQ配置改为占位符形式,默认值保留localhost(方便本地开发测试),容器启动时自动读取环境变量值:
spring: rabbitmq: host: ${SPRING_RABBITMQ_HOST:localhost} port: ${SPRING_RABBITMQ_PORT:5672} username: ${SPRING_RABBITMQ_USERNAME:guest} password: ${SPRING_RABBITMQ_PASSWORD:guest} rabbit: rates-queue-name: rates_queue
修改后重新构建Spring Boot jar包,更新Docker镜像,再启动Docker Compose即可。
方法二:使用外部配置文件覆盖jar内配置
在currency-provider项目根目录创建application-docker.yml,配置Docker环境下的RabbitMQ连接信息:
spring: rabbitmq: host: rabbit port: 5672 username: guest password: guest
修改Dockerfile,复制该配置文件到容器,并指定启动时使用docker配置文件:
FROM openjdk:17-alpine ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar COPY application-docker.yml /application-docker.yml ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=docker"]
此方法无需依赖环境变量,配置更直观。
方法三:确保环境变量优先级生效
确认你的Spring Boot版本为2.x及以上(该版本默认支持环境变量覆盖jar内配置),如果是旧版本建议升级到稳定版。同时检查应用代码中是否存在自定义PropertySource注解,避免环境变量被忽略。
额外优化:解决RabbitMQ服务就绪问题
depends_on仅保证容器启动顺序,不保证RabbitMQ服务完全就绪。可以添加健康检查,让应用等待RabbitMQ就绪后再启动:
在docker-compose.yml的rabbit服务中添加健康检查:
rabbit: container_name: rabbit image: rabbitmq:3-management ports: - "5672:5672" - "15672:15672" networks: - exchange healthcheck: test: ["CMD", "rabbitmq-diagnostics", "ping"] interval: 10s timeout: 5s retries: 5
修改currency-provider的depends_on配置:
currency-provider: # ... 其他配置 depends_on: rabbit: condition: service_healthy
内容的提问来源于stack exchange,提问作者pompomek

