Document setting eureka instance id when running multiple local apps use 'server.port=0'
Trying to run multiple local instances of a service for 'testing' purposes.
I set 'server.port=0' on my local app so that when I launch an instance it picks its own port. Convenient it you want to run more than one. And I would imagine this a good fit with Eureka too since i'd hope registering the instances with eureka they would then all become known to the clients of my service.
This all seems to work... except that if start more than one instance only one of the gets effectively registered with eureka.
I think the problem is the default instance id being picked is not unique:
Described here: http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_eureka_metadata_for_instances_and_clients
It is an expression that contains "${server.port}" which evaluates to 0 regardles of what port was dynamically allocated.
Logically... I think this is wrong. It should not be using "server.port" but it should use the actual port the app is running on. If it did that, then it would all just work flawlessly without me having to configure something like this to fix this problem:
eureka:
instance:
instance-id: ${spring.application.name}:${random.int}
I'm not really sure this is a 'bug' or a 'feature'. But it seems incorrect to me to use 'server.port' when the intention is probably for this to be the port the app is actually running on, which it not if "server.port=0".
In case it helps... a pointer to the sample at the exact commit where I produced this problem (the fix is commented out).
https://github.com/kdvolder/date-service-sample/blob/8da26e2ecbac930494db6a5fa73706c8f5b425ae/date-service/src/main/resources/application.yml
@kdvolder I think eureka.instance.instance-id: ${spring.application.name}:${random.int} is a fine workaround. I wish using random ports had never been a feature, it's very brittle with eureka. I'm thinking the fix here is to document the random.int part when using server.port=0, what do you think @dsyer .
I tried using "local.server.port" but that didn't seem to work either (is there some property one could read that has the actual server port? If so, then that should be used. If there isn't... then maybe there should be :-)
The trouble is, we don't know the port until the container has given it to spring boot, much later than when eureka needs it.
But it seems Eureka does know the actual port somehow. Because the one instance that does get connected is accessible by clients that obtain a reference to it through Eureka. (I raised a bug about that being broken a while back... and you fixed that somehow). Isn't this a similar problem? Can't it be fixed the same way (however you did that piece of magic :-)
Anyhow... I'm probably too naive as I have no idea how this stuff is all really wired together.
I won't object if you think its too hard to fix and would rather opt to document it clearly.
For instanceId, I think I'll stick to the documentation. :-) Running multiple instances on a single host with a random port, seems like an edge case and not likely to run in production. If someone is, it's a small bit of config.
I'm facing the same issue. I got 2 servers in the same machine, also for test purposes, but Eureka can only see one. Here is my config
spring:
profiles.active: default
---
server:
compression.enabled: true
port: 0
spring:
profiles: default
application:
name: contacts-service
params:
datasource:
driverClassName: org.postgresql.Driver
jdbcUrl: jdbc:postgresql://127.0.0.1:5432/contacts
username: postgres
password: postgres
maximumPoolSize: 2
poolName: hikari_contacts_pool
spring.jpa:
show-sql: true
hibernate:
ddl-auto: update
eureka:
client:
registryFetchIntervalSeconds: 5
serviceUrl:
defaultZone: http://eureka:[email protected]:8761/eureka/
instance:
preferIpAddress: true
leaseRenewalIntervalInSeconds: 10
metadataMap:
instanceId: ${spring.application.name}:${random.int}
I have the feeling that even if deploy this app in multiple machines, I'll still see this problem, if this is related to the instanceId thing
@spencergibb what do you think?
Hi I'm facing the same issue. Starting multiple tomcat instances in random ports (server.port=0), but eureka is registering only the last instance started i.e., if I start tomcat on port 8080, eureka will detect it and register it. But if other tomcat instance starts on, for example, port 8081, this instance will overwrite the old instance and only 8081 will be visible by eureka. I would appreciate some guidance on that matter. Thanks, Felipe
@felipeazv the problem is that both apps have the same instanceId which, by default uses server.port, which, for both apps, is 0, therefore the same instanceId. Setting a unique instanceId will fix the problem:
https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#changing-the-eureka-instance-id
@spencergibb big thanks!
what is the differnt betwenn eureka with aws and eureka with netfix ?
@kdvolder For sever setting up a unique instance id please try with eureka:
instance:
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
@luizkowalski If you have 2 Eureka instances you should have 2 profiles for each instance. To enable peering you have to interchange server IP in each setting. Example:
spring:
profiles: peer 1
server:
port: 8761
eureka:
client:
serviceUrl:
defaultZone: http://<peer 2>:<port>/eureka/
spring:
profiles: peer 2
server:
port: 8761
eureka:
client:
serviceUrl:
defaultZone: http://<peer 1>:<port>/eureka/