Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing status on Eureka instance affects all instances on same host #63

Closed
abaculus opened this issue Nov 11, 2014 · 15 comments
Closed

Comments

@abaculus
Copy link

Setup:

  • Starting Eureka Server on localhost
  • Two running instances of a service registered with the Eureka server on localhost (different app names)
  • All instances has status UP when starting

When invoking REST endpoint:

http://localhost:8761/v2/apps/SAMPLE-EUREKA-SERVICE-8042/MYHOST57/status?value=DOWN

, all service instances will change status to 'DOWN' on the same host.

eureka-change-status

What am I doing wrong?

Regards,
Andreas

@dsyer
Copy link
Contributor

dsyer commented Nov 11, 2014

Don't know. But /v2 is not used as a prefix any more, it's now /eureka by default. Did you change it or would an upgrade be a good idea? Also "MYHOST57" doesn't match the service id in the UI (not sure if that matters but it looks wrong).

@abaculus
Copy link
Author

Aha, didn't know about the /v2 prefix. I got the /eureka prefix working but it still puts both services down.

I can send you my sample code if you want?

PS. About the "MYHOST57", it's a typo.

@abaculus
Copy link
Author

Found these issues at Netflix Eureka:

Hostname reused as InstanceId disallows multiple service instances on 1 host

Added the UniqueIdentifier interface

How can I supply a custom DataCenterInfo using Spring?

Here's how to do it without Spring:

DiscoveryManager.getInstance().initComponent(
                new MyDataCenterInstanceConfig("myNamespace.", new MyDataCenterInfo()),
                new DefaultEurekaClientConfig());

@dsyer
Copy link
Contributor

dsyer commented Nov 12, 2014

How are your client apps registering? If they are Spring Cloud apps they should have unique ids already (we have samples that work on localhost just fine).

If you need to customize the EurekaClientConfig it's best to use the Spring Boot external properties ('eureka.client.*`), but you can't customize the data center info that way (I'm not sure you need to though to solve this problem).

@abaculus
Copy link
Author

My client app has the following config:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
public class SampleEurekaService {
    ....
}

And my application.properties:

server.port=8042
spring.application.name=sample-eureka-service-${server.port}
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

@dsyer
Copy link
Contributor

dsyer commented Nov 12, 2014

Based on that, I'd expect the Eureka ID to be "MYHOST57:sample-eureka-service-8042:8042". Are you messing around with the DiscoveryClient or the EurekaClientConfig or something?

@abaculus
Copy link
Author

Here's my complete Eureka client application (manually wiring the HealthCheckHandler since I'm running 1.0.0.M2 version):

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
public class SampleEurekaService {

    private static final String DISCOVERY_CLIENT_BEAN_NAME = "discoveryClient";

    @Autowired
    private DiscoveryClient discoveryClient;

    public static void main(String[] args) {
        final ConfigurableApplicationContext context = SpringApplication.run(
                SampleEurekaService.class, args);

        final DiscoveryClient discoveryClient = context.getBean(
                DISCOVERY_CLIENT_BEAN_NAME, DiscoveryClient.class);

        discoveryClient.registerHealthCheck(new DefaultHealthCheckHandler());
    }

}

@dsyer
Copy link
Contributor

dsyer commented Nov 12, 2014

OK, I see what's happening. The sample apps have something like this:

eureka:
  instance:
    metadataMap:
      instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}

I guess we need to maybe promote that to a default, but you can follow the same pattern to get your instances to show up as different IDs in Eureka.

@abaculus
Copy link
Author

Adding this to my config and I cannot longer call:

http://localhost:8761/eureka/apps/SAMPLE-EUREKA-SERVICE-8042/ANSTOLAP57/status?value=DOWN

According to http://localhost:8761/eureka/apps the application name is SAMPLE-EUREKA-SERVICE-8042 and the instanceId (under metadata) is sample-eureka-service-8042:8042 and hostname is ANSTOLAP57.

Do you know how I can call the status URL using the suggested pattern for instanceId?

@abaculus
Copy link
Author

Ok, I got it:

http://localhost:8761/eureka/apps/SAMPLE-EUREKA-SERVICE-8042/ANSTOLAP57:sample-eureka-service-8042:8042/status?value=DOWN

Would be great to have this instance_idpattern as a default!

Thanks!

@abaculus
Copy link
Author

I just saw this is my log when closing service:

Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@b353d4: startup date [Wed Nov 12 14:13:42 CET 2014]; root of context hierarchy
 Stopping beans in phase 0
 Finished a call to service url http://localhost:8761/eureka/ and url path apps/SAMPLE-EUREKA-SERVICE-8091/ANSTOLAP57 with status code 404.
 Action: Cancel  => returned status of 404 from http://localhost:8761/eureka/apps/SAMPLE-EUREKA-SERVICE-8091/ANSTOLAP57
 Can't get a response from http://localhost:8761/eureka/apps/SAMPLE-EUREKA-SERVICE-8091/ANSTOLAP57

When closing it does not use the instance_id from metadata.

@dsyer
Copy link
Contributor

dsyer commented Nov 12, 2014

Interesting. Maybe that explains some of the problems reported in #47.

dsyer added a commit that referenced this issue Nov 13, 2014
The problem manifests itself as errors in the Eureka server
log (gh-47), but originates in the client because it is sending
requests to /eureka/apps/{NAME}/{ID} with the wrong ID. The
InstanceInfo has an ID that is derived (for preference) from
the EurekaInstanceConfig.dataCenterInfo, so that's the best
way to fix it.

See gh-63, Fixes gh-47
@abaculus
Copy link
Author

Found another issue related to this.

If using the feature Discover the HTTP port at runtime in Spring Boot, i.e. setting property server.port=0 the instance id is no longer unique even tough each service gets an unique port since the property server.port is used instead of local.server.port.

Is this something that could be done by checking if the local.server.port has been set before assigning the instance id to EurekaInstanceConfig?

I'm currently using following pattern to make unique instanceId:

eureka.instance.metadataMap.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}

@dsyer
Copy link
Contributor

dsyer commented Nov 20, 2014

That might be the best solution when server.port=0 (the actual port is not known until the container starts which is after the application context gets its ID, and the config beans are bound). We can certainly document this if it turns out to be best practice. Note that in Cloud Foundry there is a vcap.application.instance_id, and probably in other PaaS platforms there is something similar.

@Haybu
Copy link
Contributor

Haybu commented Nov 21, 2014

thanks Dave for pointing me out to this post, I'm able now to register multiple service instances by setting a metadata of

eureka.instance.metadataMap.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}

thanks abaculus for the suggestion.

@dsyer dsyer added this to the 1.0.0.RC1 milestone Dec 4, 2014
@dsyer dsyer closed this as completed in fc0aac3 Dec 4, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants