Search code examples
spring-bootdockermicroservicesnetflix-eureka

Spring Boot microservices - dependency


There are two microservices deployed with docker compose. A dependecy between services is defined in docker compose file by depends_on property. Is it possible to achieve the same effect implicitly, inside the spring boot application?

Let's say the microservice 1 depends on microservice 2. Which means, microsearvice 1 doesn't boot up before microservice 2 is healthy or registered on Eureka server.


Solution

  • By doing some research, I found a solution to the problem.

    Spring Retry resolves dependency on Spring Cloud Config Server. Maven dependency spring-retry should be added into the pom.xml, and the properties below into the .properties file:

    spring.cloud.config.fail-fast=true
    spring.cloud.config.retry.max-interval=2000
    spring.cloud.config.retry.max-attempts=10
    

    The following configuration class is used to resolve dependency on other microservices.

    @Configuration
    @ConfigurationProperties(prefix = "depends-on")
    @Data
    @Log
    public class DependsOnConfig {
    
        private List<String> services;
        private Integer periodMs = 2000;
        private Integer maxAttempts = 20;
    
        @Autowired
        private EurekaClient eurekaClient;
    
        @Bean
        public void dependentServicesRegisteredToEureka() throws Exception {
            if (services == null || services.isEmpty()) {
                log.info("No dependent services defined.");
                return;
            }
            log.info("Checking if dependent services are registered to eureka.");
            int attempts = 0;
            while (!services.isEmpty()) {
                services.removeIf(this::checkIfServiceIsRegistered);
                TimeUnit.MILLISECONDS.sleep(periodMs);
                if (maxAttempts.intValue() == ++attempts)
                    throw new Exception("Max attempts exceeded.");
            }
        }
    
        private boolean checkIfServiceIsRegistered(String service) {
            try {
                eurekaClient.getNextServerFromEureka(service, false);
                log.info(service + " - registered.");
                return true;
            } catch (Exception e) {
                log.info(service + " - not registered yet.");
                return false;
            }
        }
    
    }
    

    A list of services that the current microservice depends on are defined in .properties file:

    depends-on.services[0]=service-id-1 
    depends-on.services[1]=service-id-2  
    

    A bean dependentServicesRegisteredToEureka is not being initialized until all services from the list register to Eureka. If needed, annotation @DependsOn("dependentServicesRegisteredToEureka") can be added to beans or components to prevent attempting an initialization before dependentServicesRegisteredToEureka initialize.