问题描述
可以从 localhost:8888 访问配置服务器,但是当我在 SCDF 上部署我的应用程序时出现以下错误:
Fetching config from server at : http://localhost:8888
2021-07-30 14:58:53.535 INFO 143 --- [ main] o.s.b.context.config.ConfigDataLoader : Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available
2021-07-30 14:58:53.535 WARN 143 --- [ main] o.s.b.context.config.ConfigDataLoader : Could not locate PropertySource ([configserverConfigDataResource@3de88f64 uris = array<String>['http://localhost:8888'],optional = true,profiles = list['default']]): I/O error on GET request for "http://localhost:8888/backend-service/default": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
除了配置服务器连接之外,应用程序在 SCDF 上成功部署。我在 SCDF 中指定的唯一属性是 docker 网络。我正在使用 spring.config.import 并且没有使用任何引导程序。这在本地部署时一切正常,但在 SCDF 上部署时,微服务无法连接到配置服务器。
Spring Boot 版本:2.5.1
应用属性
spring.application.name=backend-service
spring.cloud.config.fail-fast=true
spring.cloud.config.retry.max-attempts=6
spring.cloud.config.retry.max-interval=11000
spring.config.import=optional:configserver:http://localhost:8888
配置服务器属性
spring.cloud.config.server.git.uri=...
management.endpoints.web.exposure.include=*
spring.cloud.config.fail-fast=true
spring.cloud.config.retry.max-attempts=6
spring.cloud.config.retry.max-interval=11000
spring.cloud.bus.id=my-config-server
spring.cloud.stream.rabbit.bindings.springCloudBus.consumer.declareExchange=false
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.cloud.bus.enabled=true
spring.cloud.bus.refresh.enabled: true
spring.cloud.bus.env.enabled: true
server.port=8888
docker-compose.yml
version: '3.1'
services:
h2:
...
rabbitmq-container:
image: rabbitmq:3.7.14-management
hostname: dataflow-rabbitmq
expose:
- '5672'
ports:
- "5672:5672"
- "15672:15672"
networks:
- scdfnet
dataflow-server:
...
networks:
- scdfnet
app-import:
...
networks:
- scdfnet
skipper-server:
...
networks:
- scdfnet
configserver-container:
image: ...
ports:
- "8888:8888"
expose:
- '8888'
environment:
- spring_rabbitmq_host=rabbitmq-container
- spring_rabbitmq_port=5672
- spring_rabbitmq_username=guest
- spring_rabbitmq_password=guest
depends_on:
- rabbitmq-container
networks:
- scdfnet
networks:
scdfnet:
external:
name: scdfnet
volumes:
h2-data:
解决方法
对于遇到此问题的其他人,我找到了两种解决方法。问题在于,一旦 Spring Boot 应用程序被容器化,属性文件中引用的 localhost 将导致程序获取应用程序容器虚拟网络的 localhost,而不是本地机器的 localhost。
针对相同的错误有许多 Stack Overflow 的答案,但都围绕着对引导程序属性的更正。但是,自 Spring Boot 2.4 起不推荐使用 bootstrap 上下文初始化。
第一个解决方案是使用您的 IPv4 地址而不是 localhost。
spring.config.import=configserver:http://<insert IPv4 address>:8888
例如:
spring.config.import=configserver:http://10.6.39.148:8888
比硬接线地址更好的解决方案是引用在 docker compose 中运行的配置服务器容器:
spring.config.import=optional:configserver:http://configserver-container:8888
确保所有 Docker Compose 服务都在同一网络上运行(在我的情况下为 scdf_network),并注意此地址仅在 docker-compose 上运行时才有效,因此如果您在 Eclipse 上构建 maven 文件,您可能需要删除或禁用您的测试才能成功构建。这可能是不必要的;可能只是我未能将某些属性复制到我的本地 application.properties 文件,这导致上下文测试失败。根据 documentation,optional 标签应该允许配置客户端运行,即使无法与配置服务器建立联系。