Register multiple Instances of a Spring Boot Eureka Client from a single host
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
mcwumbly
Updated on July 24, 2022Comments
-
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 ofeureka-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 namefoo
and the port8081
.In a minute or so, the
/instances
endpoint will show the information about thisfoo
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 forhttp://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 onhttp://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 about 8 yearsThanks, 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 withmvn spring-boot:run -Dserver.port8082 -Deureka.instance.metadataMap.instanceId=instance2
and it shows up in the dashboard and the response from theDiscoveryClient
now. -
Divs over 7 yearsI found
{namespace}.instanceId
to be working and noteureka.instance.metadataMap.instanceId
with the eureka master branch as of today. -
rfoltyns over 7 yearsMaybe it got deprecated and finally removed - IMHO namespaces are more robust. I'll verify it in the underlying impl. Thanks for the update.