Spring Cloud Config Server 无法与 Docker 组合一起使用
Posted
技术标签:
【中文标题】Spring Cloud Config Server 无法与 Docker 组合一起使用【英文标题】:Spring Cloud Config Server not working with Docker compose 【发布时间】:2017-11-28 00:56:40 【问题描述】:我有一个 Spring Cloud 配置服务器并将其打包为 Docker 映像,然后我有 Spring Cloud Eureka 服务器,它也打包为 Docker 映像。
当我使用 docker compose 运行这两个时,出现以下错误。
discovery-service_1 | 2017-06-24 15:36:12.059 INFO 5 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://config-service:9001
discovery-service_1 | 2017-06-24 15:36:12.997 WARN 5 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://config-service:9001/cls-discovery-service/default": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
虽然配置服务已经启动并成功运行,但是发现服务由于某种原因仍然没有找到它。
这里使用的 Docker compose 文件是这个
version: '2'
services:
config-service:
image: cloudsea/cls-config-service
ports:
- 9001:9001
expose:
- "9001"
discovery-service:
image: cloudsea/cls-discovery-service
depends_on:
- config-service
environment:
CLOUD_SEA_CONFIG_SERVER_URI: http://config-service:9001
EUREKA_DEFAULT_ZONE_URL: http://discovery-service:8761/eureka/
ports:
- 8761:8761
links:
- config-service:config-service
下面是 DISCOVERY SERVICE 的 bootstrap.properties
spring.cloud.config.uri = $CLOUD_SEA_CONFIG_SERVER_URI:http://localhost:9001
spring.application.name = $SPRING_APPLICATION_NAME:cls-discovery-service
下面是位于 github 中的 DISCOVERY SERVICE 的 cls-discovery-service.properties。
server.port=$SERVER_PORT:8761
eureka.client.registerWithEureka: false
eureka.client.fetchRegistry: false
eureka.client.serviceUrl.defaultZone: $EUREKA_DEFAULT_ZONE_URL:http://localhost:8761/eureka/
eureka.server.eviction-interval-timer-in-ms: 1000
我假设我的 docker-compose.yml 有问题,但我不确定。
任何帮助我都会坚持几个小时...接近几天:(
【问题讨论】:
单独运行docker镜像怎么样?先运行“config-service”,再运行“discovery-service”? 如果我这样做,它可以完美运行,但问题是我必须将配置 uri 指定为http://DOCKER_HOST:9001
。我假设问题出在 docker compose 但不知道它是什么???
【参考方案1】:
我通过将此配置添加到 发现服务的 bootstrap.yml 解决了这个问题。
spring:
cloud:
config:
failFast: true
retry:
initialInterval: 3000
multiplier: 1.3
maxInterval: 5000
maxAttempts: 20
然后将 spring-boot-starter-aop 和 spring-retry 添加到 discovery 服务的 maven 依赖项。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>$spring-boot-starter-aop.version</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>$spring-retry.version</version>
</dependency>
问题是它们都是同时开始的。但是发现服务依赖于配置服务。
当您启动发现服务时,它会一遍又一遍地说“Fetching config from server”,直到配置服务启动。
配置服务启动后,发现服务将成功获取其配置,然后它会自行启动。
【讨论】:
我花了两天时间面对这个问题,所以我找到了这个答案,非常感谢。【参考方案2】:问题是所有 docker 容器将一起启动,但根据您的架构,配置服务需要先启动,然后是发现服务(eureka)。所以发现服务给出了错误。
depends_on
在启动发现服务之前不等待配置服务“准备好” - 它只等到它启动。如果您需要等待服务就绪,则必须使用控制启动顺序。
根据建议,您可以将 API/服务设置为每隔一段时间重试一次,直到配置服务器启动。
虽然,我也更喜欢使用 depends_on 或 healthcheck 并控制启动顺序,如下所示:
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
wait-for-it.sh 是一个纯 bash 脚本,它将等待可用性。我还建议研究容器编排工具,如 docker-swarm 或 kubernetes。
【讨论】:
【参考方案3】:我也遇到过同样的问题,并且被卡住了一段时间,我正要走与春季重试相同的路线,这不是一个糟糕的模式,它确实将弹性嵌入到您的应用程序中,但是这里的主要问题是 docker 的启动顺序不合适。我将分享我的工作 docker-compose 文件,它非常相似,但这里的关键是“depends_on”参数。我在我的论点上添加了引号,它似乎有效。
version: "2"
services:
eureka:
image: eurekatest
ports:
- "8761:8761"
config:
image: config
ports:
- "8888:8888"
links:
- eureka:eureka
depends_on:
- "eureka"
【讨论】:
以上是关于Spring Cloud Config Server 无法与 Docker 组合一起使用的主要内容,如果未能解决你的问题,请参考以下文章
spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server的区别
spring-cloud-config:spring-cloud-config Maven配置错误
无法通过 spring.cloud.config.enabled:false 禁用 Spring Cloud Config