Spring Cloud Config Eureka-first approach not working

17,150

You need the eureka serviceUrl in the bootstrap.yml (as well as the service id of the configserver).

Share:
17,150
chrx
Author by

chrx

I have a Laurea degree (MS) with Laude in "Scienze dell'Informazione" (computer sciences and information sciences), from the University of Genoa, Italy. As a Research Team Leader I've been involved since 1998 in several research projects funded by European Commission in the context of different framework programmes from FP4 to FP7 till, currently, Horizon-2020. The projects I've been involved ranged from the sectors of Content and Knowledge Management, ICT Solutions for Collaborative Work, Semantic Web technologies and others. During these years, I've been specifically in charge of the design of software architectures, elicitation and formalization of user requirements, knowledge formalization and modelling, and was often charged with technical coordination and integration tasks. I am strongly committed to innovation, and have specific expertise in design and development of enterprise-level Java-based distributed applications, but also have experience in a wide range of other distributed-systems and cloud-related technologies.

Updated on June 14, 2022

Comments

  • chrx
    chrx almost 2 years

    I'm developing a Spring Cloud Eureka microservices application. I want my services to connect to the config service via an Eureka-first approach. Microservices are packaged as docker containers and deployed via docker-compose. The application is composed by:

    1. myapp-service-registry: a service registry service implemented with Spring Cloud Eureka
    2. myapp-config-service: a Spring Cloud config service server
    3. myapp-service-test: An example microservice which should try to take its config data from the config service by connecting to this via an Eureka-first approach.

    The connection to the config service fail as described below. First of all some configuration data:

    Here is myapp-service-registry's application.yml:

    server:
      port: ${PORT:8761}
    
    eureka:
      client:
        registerWithEureka: false
        fetchRegistry: false
      server:
        waitTimeInMsWhenSyncEmpty: 0
    

    Here the myapp-config-service's application.yml:

    server:
      port: ${MYAPP_CONFIG_SERVICE_PORT:8888}
    
    spring: 
      cloud:
        config:
          server:
            git:
              uri: ${MYAPP_CONFIG_SERVICE_GIT_URI}
      config:
        name: myapp-config-service
    
    # eureka service registry client
    
    eureka: 
        client:
            serviceUrl:
                defaultZone: http://${SERVICE_REGISTRY_HOST}:${SERVICE_REGISTRY_PORT}/eureka/
        instance:
            preferIpAddress: true
    

    Config server and client are initialized as in configserver-eureka and eureka-first samples in https://github.com/spring-cloud-samples/tests :

    myapp-config-service's bootstrap.yml is:

    spring:
        application:
            name: myapp-config-service
        cloud:
            config:
                discovery:
                    enabled: true
    

    And myapp-service-test's application.yml:

    eureka:
        client:
            serviceUrl:
                defaultZone: http://${SERVICE_REGISTRY_HOST}:${SERVICE_REGISTRY_PORT}/eureka/
        instance:
            preferIpAddress: true
    

    And myapp-service-test's bootstrap.yml:

    spring:
      application:
        name: myapp-service-test
      cloud:
        config:
          discovery:
            enabled: true
            serviceId: myapp-config-service
    

    Following is the docker-compose.yml (env variable are replaced with actual values at launch):

    myapp-service-registry:
    image: myapp/myapp-service-registry:0.0.1
    ports:
        - ${EUREKA_PORT}:${EUREKA_PORT}
    
    # myapp-config-service
    
    myapp-config-service:
        image: myapp/myapp-config-service:0.0.1
        volumes:
        - ${MYAPP_DATA_FOLDER}/config:/var/opt/myapp/config
        environment:
          MYAPP_CONFIG_SERVICE_PORT: ${MYAPP_CONFIG_SERVICE_PORT}
          SERVICE_REGISTRY_HOST: ${MYAPP_STAGING_IP}
          SERVICE_REGISTRY_PORT: ${EUREKA_PORT}
          MYAPP_CONFIG_SERVICE_GIT_URI: ${MYAPP_CONFIG_SERVICE_GIT_URI}
        ports:
            - ${MYAPP_CONFIG_SERVICE_PORT}:${MYAPP_CONFIG_SERVICE_PORT}
    
     # myapp-service-test
    
    myapp-service-test:
      image: myapp/myapp-service-test:0.0.1
      environment:
        SERVICE_REGISTRY_HOST: ${MYAPP_STAGING_IP}
        SERVICE_REGISTRY_PORT: ${EUREKA_PORT}
      ports:
        - ${MYAPP_SERVICE_TEST_TWO_PORT}:8080
    

    I can check that Eureka is working by connecting the browser to http://[...MACHINE-IP...]:8761/ and seeing the Eureka dashboard. Similarly, I test that the config service is working and responds to http:///[...MACHINE-IP...]:8888/myapp-config-service; With the above configuration, on the other hand, myapp-service-test crashes at startup with the following log:

    -02-03 08:26:45.191  INFO 1 --- [           main] e.f.s.two.TestServiceApplication      : Starting TestServiceApplication v0.0.1 on b1bc37422027 with PID 1 (/app.jar started by root in /)
    2016-02-03 08:26:45.223  INFO 1 --- [           main] e.f.s.two.TestServiceApplication      : No active profile set, falling back to default profiles: default
    2016-02-03 08:26:45.448  INFO 1 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4d97e82d: startup date [Wed Feb 03 08:26:45 UTC 2016]; root of context hierarchy
    2016-02-03 08:26:46.382  INFO 1 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2016-02-03 08:26:46.442  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [class org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$6b65138e] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2016-02-03 08:26:47.089  INFO 1 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
    2016-02-03 08:26:48.231  INFO 1 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using encoding codec LegacyJacksonJson
    2016-02-03 08:26:48.237  INFO 1 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using decoding codec LegacyJacksonJson
    2016-02-03 08:26:49.171  INFO 1 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using encoding codec LegacyJacksonJson
    2016-02-03 08:26:49.171  INFO 1 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using decoding codec LegacyJacksonJson
    2016-02-03 08:26:49.496  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
    2016-02-03 08:26:49.497  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
    2016-02-03 08:26:49.497  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
    2016-02-03 08:26:49.498  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
    2016-02-03 08:26:49.502  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
    2016-02-03 08:26:49.503  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
    2016-02-03 08:26:49.503  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
    2016-02-03 08:26:49.720  WARN 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Can't get a response from http://localhost:8761/eureka/apps/
    <...>
    com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused
        at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.jar!/:1.19]
        at com.sun.jersey.api.client.filter.GZIPContentEncodingFilter.handle(GZIPContentEncodingFilter.java:123) ~[jersey-client-1.19.jar!/:1.19]
        at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.3.4.jar!/:1.3.4]
        <...>
    Caused by: java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_66-internal]
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_66-internal]
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_66-internal]
        <...>
    
    2016-02-03 08:26:49.747 ERROR 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Can't contact any eureka nodes - possibly a security group issue?
    
    com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused
        <...>
    
    2016-02-03 08:26:49.770 ERROR 1 --- [           main] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MYAPP-SERVICE-TEST/b1bc37422027:myapp-service-test - was unable to refresh its cache! status = java.net.ConnectException: Connection refused
    
    com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused
        <...>
    
    2016-02-03 08:26:49.785  WARN 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Using default backup registry implementation which does not do anything.
    2016-02-03 08:26:49.810  INFO 1 --- [           main] com.netflix.discovery.DiscoveryClient    : Starting heartbeat executor: renew interval is: 10
    2016-02-03 08:26:49.818  INFO 1 --- [           main] c.n.discovery.InstanceInfoReplicator     : InstanceInfoReplicator onDemand update allowed rate per min is 4
    2016-02-03 08:26:50.443  WARN 1 --- [           main] lientConfigServiceBootstrapConfiguration : Could not locate configserver via discovery
    
    java.lang.RuntimeException: No matches for the virtual host name :myapp-config-service
        at com.netflix.discovery.DiscoveryClient.getNextServerFromEureka(DiscoveryClient.java:782) ~[eureka-client-1.3.4.jar!/:1.3.4]
        at org.springframework.cloud.netflix.config.DiscoveryClientConfigServiceBootstrapConfiguration.refresh(DiscoveryClientConfigServiceBootstrapConfiguration.java:71) [spring-cloud-netflix-core-1.1.0.M3.jar!/:1.1.0.M3]
        <...>
    
    2016-02-03 08:26:50.470  INFO 1 --- [           main] e.f.s.two.TestServiceApplication      : Started TestServiceApplication in 7.101 seconds (JVM running for 9.329)
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v1.3.1.RELEASE)
    
    2016-02-03 08:26:50.773  INFO 1 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
    2016-02-03 08:26:51.015  WARN 1 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://localhost:8888/myapp-service-test/default":Connection refused; nested exception is java.net.ConnectException: Connection refused
    
    <...>
    
    2016-02-03 08:26:54.856 ERROR 1 --- [pool-5-thread-1] com.netflix.discovery.DiscoveryClient    : Can't contact any eureka nodes - possibly a security group issue?
    
    com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused
        <...>
    
    2016-02-03 08:26:57.272  WARN 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testTwoServiceController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: java.lang.String myapp.services.two.TestServiceController.message; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'message' in string value "${message}"
    2016-02-03 08:26:57.281  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service Tomcat
    2016-02-03 08:26:57.299 ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    

    Note that if I don't implement an Eureka-first approach (and set spring.cloud.config.uri directly in the service's bootstrap.yml), the service registers to Eureka, finds the config server and works correctly (I can see the registered service in Eureka's dashboard and can check that config properties are correctly read).