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-aopspring-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-server

无法通过 spring.cloud.config.enabled:false 禁用 Spring Cloud Config

0701-spring cloud config-简介Config Server开发Config Client开发

问题 spring-cloud-config 和 spring-cloud-bus