spring-cloud-netflix icon indicating copy to clipboard operation
spring-cloud-netflix copied to clipboard

Document setting eureka instance id when running multiple local apps use 'server.port=0'

Open kdvolder opened this issue 9 years ago • 13 comments

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".

kdvolder avatar Feb 22 '16 22:02 kdvolder

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 avatar Feb 22 '16 22:02 kdvolder

@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 .

spencergibb avatar Feb 22 '16 23:02 spencergibb

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 :-)

kdvolder avatar Feb 22 '16 23:02 kdvolder

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.

spencergibb avatar Feb 22 '16 23:02 spencergibb

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.

kdvolder avatar Feb 22 '16 23:02 kdvolder

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.

spencergibb avatar Feb 22 '16 23:02 spencergibb

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

luizkowalski avatar Mar 26 '16 22:03 luizkowalski

@spencergibb what do you think?

luizkowalski avatar Mar 30 '16 19:03 luizkowalski

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 avatar Oct 26 '16 01:10 felipeazv

@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 avatar Oct 26 '16 18:10 spencergibb

@spencergibb big thanks!

felipeazv avatar Oct 26 '16 23:10 felipeazv

what is the differnt betwenn eureka with aws and eureka with netfix ?

kushankavinda avatar Feb 02 '19 05:02 kushankavinda

@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/

orias407 avatar Feb 02 '19 05:02 orias407