Search code examples
spring-bootspring-cloudmicroservicesnetflix-eurekanetflix-ribbon

Load Balancing in Spring Cloud / Netflix OSS


I am looking at Spring Boot / Cloud and Netflix FWs (Eureka, Ribbon). I am working through this example:

https://spring.io/blog/2015/07/14/microservices-with-spring Basically it is about some small Spring Boot microservices that use the Eureka Service Registry.

I now want to start several instances of the same service (in this example the AccountService, on different ports). Everything I read (above article, http://callistaenterprise.se/blogg/teknik/2015/04/10/building-microservices-with-spring-cloud-and-netflix-oss-part-1/ etc) suggests that if I do this, all instances get registered with Eureka redundantly and when I call the service, client-side load balancing is applied and the service to call is dynamically chosen.

However, this is NOT what happens. When I start the first service instance, it gets registered and shows up in the Eureka Dashboard. When I start the same service on a different port, it also registers, but it seems to REPLACE the previous service instance: The Eureka Dashboard still only shows one instance with Availability Zones = 1 (should be 2?) and ALL calls to this service are handled by the second instance. When I query the registry, only this instance is applied.

When I stop the second instance, after some time Eureka switches back to the first one and it still works. So it seems to keep all instances, but only ever uses the instance that was registered latest.

Do I miss anything important? I thought all instances should be used simultaneously?

========== Application Properties are (those are practically unchanged to the example from the Spring Site):

EurekaServer

eureka:  
  instance:  
    hostname: localhost  
  client:    
    registerWithEureka: false  
    fetchRegistry: false  

server:  
  port: 1111     

spring:  
  thymeleaf:  
    enabled: false  

AccountsServer

spring:  
  application:  
    name: accounts-service  
  freemarker:  
    enabled: false           
  thymeleaf:  
    cache: false             
    prefix: classpath:/accounts-server/templates/      

eureka:  
  client:  
    serviceUrl:  
      defaultZone: http://localhost:1111/eureka/  

server:  
  port: 4444   # HTTP (Tomcat) port, for the second instance this is changed to a different port

Solution

  • @dshuld if you are using the Angel release train or version 1.0.x you need to make each instance have a unique id. See the docs here. Something like:

    eureka:
      instance:
        metadataMap:
          instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
    

    For the Brixton release train (1.1.x) it should have a sensible default.