9

I have a spring cloud config server and packaged it as a docker image then I have spring cloud eureka server which is also packaged as docker image.

When I run the two using docker compose I get the following error.

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)

Although the config service is up and running successfully, discover service still does not find it for some reason.

Docker compose file being used here is this 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

Below is the bootstrap.properties for DISCOVERY SERVICE

spring.cloud.config.uri = ${CLOUD_SEA_CONFIG_SERVER_URI:http://localhost:9001} spring.application.name = ${SPRING_APPLICATION_NAME:cls-discovery-service}

Below is the cls-discovery-service.properties for DISCOVERY SERVICE located in github.

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

I am assuming something is wrong with my docker-compose.yml but I am not sure.

Any help will I am stick in this for hours ... heading close to days :(

Shahbaz
  • 141
  • 2
  • 7
  • How about running the docker image separately? first run the "config-service", then run the "discovery-service"? – Liping Huang Jun 25 '17 at 02:35
  • If I do so it works perfectly but the catch is I have to then specify the config uri as ```http://DOCKER_HOST:9001```. I am assuming the problem is with docker compose but do not know what it is ??? – Shahbaz Jun 25 '17 at 16:08

3 Answers3

8

I solved it by adding this configuration to the discovery service's bootstrap.yml.

spring:
  cloud:
    config:
      failFast: true
      retry:
        initialInterval: 3000
        multiplier: 1.3
        maxInterval: 5000
        maxAttempts: 20

Then add spring-boot-starter-aop and spring-retry to the discovery service's maven dependencies.

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

The problem is they're both starting at the same time. But the discovery service depends on the config service.

When you start the discovery service, it's going to say "Fetching config from server" again and again until config service is up.

After the config service starts, discovery service is going to get its configuration successfully and then it's going to start itself.

Enes Korukcu
  • 135
  • 1
  • 8
4

The problem is all the docker container will start together, but as per your architecture, the config-service needs to start first, then the discovery-service(eureka). So discovery-service is giving the error.

depends_on does not wait for config-service to be “ready” before starting discovery-service - it only waits until it is started. If you need to wait for a service to be ready, you have to use controlling startup order.

As suggested about you can set the APIs/Services to keep retrying in some intervals until the config server is up.

Although, I would also prefer to use depends_on or healthcheck and controlling startup order as shown below:

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 is a pure bash script that will wait on the availability. I would also suggest looking into, container orchestration tools like docker-swarm or kubernetes.

madhu pathy
  • 429
  • 2
  • 6
1

I've faced the same issue and was stuck for a bit and I was about to go the same route as you did with the spring retry, which isn't a bad pattern to follow it does embed resiliency into your application but the main issue here is docker's launch order is out of place. I'll share my working docker-compose file, it's quite similar but the key here is the "depends_on" parameter. I've added quotes on my arguments and it seemed to work.

version: "2"
services:
  eureka:
    image: eurekatest
    ports:
    - "8761:8761"

  config: 
    image: config
    ports:
    - "8888:8888"
    links:
    - eureka:eureka
    depends_on:
    - "eureka"