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

mcwumbly picture mcwumbly · Mar 28, 2016 · Viewed 14.6k times · Source

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?

Answer

bad_habit picture bad_habit · Mar 28, 2016

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?