Register multiple Instances of a Spring Boot Eureka Client from a single host

15,485

Solution 1

For local deployments, try to configure {namespace}.instanceId property in eureka-client.properties (or eureka.instance.metadataMap.instanceId for proper yaml file in case of Spring Cloud based setup). It's deeply rooted in the way Eureka server calculates application lists and compares InstanceInfo for the PeerAwareInstanceRegistryImpl - when no more concrete data (e.g.: instance metadata is available) they try to get the id from the hostname..

I wouldn't recommend it for AWS deployment though, cause messing around with instanceId will bring you trouble figuring out which machine hosts a particular service - on the other hand I doubt that you'll hosts two identical services on one machine, right?

Solution 2

In order to get all instances show up in the admin portal by setting unique euraka.instance.hostname in your Eureka configuration file.

The hostname is used as key for storing the InstanceInfo in com.netflix.discovery.shared.Application (since no UniqueIdentifier is set). So you have to use unique hostnames. When you test ribbon in this scenario you would see that the load won't be balanced.

Following application.yml is example:

server:
  port: ${PORT:0}

info:
  component: example.server

logging:
  level:
    com.netflix.discovery: 'OFF'
    org.springframework.cloud: 'DEBUG'

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 1
    leaseExpirationDurationInSeconds: 1
    metadataMap:
      instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
    instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}

It's a bug before in Eureka, you can check further information in https://github.com/codecentric/spring-boot-admin/issues/134

Share:
15,485
mcwumbly
Author by

mcwumbly

Updated on July 24, 2022

Comments

  • mcwumbly
    mcwumbly almost 2 years

    UPDATE

    The README in this repo has been updated to demonstrate the solution in the accepted answer.


    I'm working with a simple example of a Spring Boot Eureka service registration and discovery based on this guide.

    If I start up one client instance, it registers properly, and it can see itself through the DiscoveryClient. If I start up a second instance with a different name, it works as well.

    But if I start up two instances with the same name, the dashboard only shows 1 instance running, and the DiscoveryClient only shows the second instance.

    When I kill the 2nd instance, the 1st one is visible again through the dashboard and the discovery client.

    Here are some more details about the steps I'm taking and what I'm seeing:

    Eureka Server

    Start the server

    cd eureka-server
    mvn spring-boot:run
    

    Visit the Eureka dashboard at http://localhost:8761

    Note that there are no 'Instances' yet registered

    Eureka Client

    Start up a client

    cd eureka-client
    mvn spring-boot:run
    

    Visit the client directly at http://localhost:8080/

    The /whoami endpoint will show the client's self-knowledge of its application name and port

    {
      "springApplicationName":"eureka-client",
      "serverPort":"8080"
    }
    

    The /instances endpoint will take up to a minute to update, but should eventually show all the instances of eureka-client that have been registered with the Eureka Discovery Client.

    [   
        {
          "host":"hostname",
          "port":8080,
          "serviceId":"EUREKA-CLIENT",
          "uri":"http://hostname:8080",
          "secure":false   
        } 
    ]
    

    You can also visit the Eureka dashoboard again now and see it listed there.

    Spin up another client with a different name

    You can see that another client will be registred by doing the following:

    cd eureka-client
    mvn spring-boot:run -Dspring.application.name=foo -Dserver.port=8081
    

    The /whoami endpoint will show the name foo and the port 8081.

    In a minute or so, the /instances endpoint will show the information about this foo instance too.

    On the Eureka dashboard, two clients will now be registered.

    Spin up another client with the same name

    Now try spinning up another instance of eureka-client by only over-riding the port parameter:

    cd eureka-client
    mvn spring-boot:run -Dserver.port=8082
    

    The /whoami endpoint for http://localhost:8082 shows what we expect.

    In a minute or so, the /instances endpoint now shows the instance running on port 8082 also, but for some reason, it doesn't show the instance running on port 8080.

    And if we check the /instances endpoint on http://localhost:8080 we also now only see the instance running on 8082 (even though clearly, the one on 8080 is running since that's what we're asking for.

    The Eureka dashboard only shows 1 instance of eureka-client running.

    What's going on here?

    Let's try killing the instance running on 8082 and see what happens.

    When we query /instances on 8080, it still only shows the instance on 8082.

    But a minute later, that goes away and we just see the instance on 8080 again.

    The question is, why don't we see both instances of eureka-client when they are both running?

  • mcwumbly
    mcwumbly about 8 years
    Thanks, I didn't see it before, but it looks like this is actually a duplicate of stackoverflow.com/questions/29653420/… (Small typo in the property I needed to set, it should be eureka.instance.metadataMap.instanceId) I started the second instance with mvn spring-boot:run -Dserver.port8082 -Deureka.instance.metadataMap.instanceId=instance2 and it shows up in the dashboard and the response from the DiscoveryClient now.
  • Divs
    Divs over 7 years
    I found {namespace}.instanceId to be working and not eureka.instance.metadataMap.instanceId with the eureka master branch as of today.
  • rfoltyns
    rfoltyns over 7 years
    Maybe it got deprecated and finally removed - IMHO namespaces are more robust. I'll verify it in the underlying impl. Thanks for the update.