Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring cloud eureka client to multiple eureka servers

Tags:

spring-cloud

I am able to get the eureka server to operate in a peer to peer mode. But one thing I am curious about is how do I get a service discovery client to register to multiple eureka servers.

My use case is this:
Say I have a service registering to one of the eureka servers (e.g. server A) and that registration is replicated to its peer. The service is actually pointing at server A. If server A goes down, and the client expects to renew with server A, how do the renewal work if server A is no longer present. Do I need to register with both and if not then how does the renewal happen if the client cannot communicate with server A. Does it have some knowledge of server B (from its initial and/or subsequent comms with A) and fail over to do its registration renewal there? That is not clear in any of the docs and I need to verify

So based on the answer, I added the following to my application.yml

eureka:
  # these are settings for the client that gets services
  client:
    # enable these two settings if you want discovery to work
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8762/eureka/, http://localhost:8761/eureka/

It only registers to the first in the comma separated list. If I switch them around the registration flips between eureka servers.

I can see that it does separate these based on comma but my guess is that Eureka does not use this underneath (from EurekaClientConfigBean.java)

    @Override
    public List<String> getEurekaServerServiceUrls(String myZone) {
        String serviceUrls = this.serviceUrl.get(myZone);
        if (serviceUrls == null || serviceUrls.isEmpty()) {
            serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
        }
        if (serviceUrls != null) {
            return Arrays.asList(serviceUrls.split(","));
        }

        return new ArrayList<>();
    }
like image 385
EvilJinious1 Avatar asked Feb 11 '15 12:02

EvilJinious1


3 Answers

I just reviewed the source code for Eureka 1.1.147. It works differently that i expected but at least I know now.

You can put multiple service urls in the set

serviceUrl:
      defaultZone: http://localhost:8762/eureka/, http://localhost:8761/eureka/

But the register action only uses the first one to register. There remaining are used only if attempting to contact the first fails.

from (DiscoveryClient.java)

   /**
     * Register with the eureka service by making the appropriate REST call.
     */
    void register() {
        logger.info(PREFIX + appPathIdentifier + ": registering service...");
        ClientResponse response = null;
        try {
            response = makeRemoteCall(Action.Register);
            isRegisteredWithDiscovery = true;
            logger.info(PREFIX + appPathIdentifier + " - registration status: "
                    + (response != null ? response.getStatus() : "not sent"));
        } catch (Throwable e) {
            logger.error(PREFIX + appPathIdentifier + " - registration failed"
                    + e.getMessage(), e);
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

which calls

private ClientResponse makeRemoteCall(Action action) throws Throwable {
    return makeRemoteCall(action, 0);
}

It only calls the backup when an exception is thrown in the above makeRemoteCall(action, 0) call

   } catch (Throwable t) {
            closeResponse(response);
            String msg = "Can't get a response from " + serviceUrl + urlPath;
            if (eurekaServiceUrls.get().size() > (++serviceUrlIndex)) {
                logger.warn(msg, t);
                logger.warn("Trying backup: " + eurekaServiceUrls.get().get(serviceUrlIndex));
                SERVER_RETRY_COUNTER.increment();
                return makeRemoteCall(action, serviceUrlIndex);
            } else {
                ALL_SERVER_FAILURE_COUNT.increment();
                logger.error(
                        msg
                                + "\nCan't contact any eureka nodes - possibly a security group issue?",
                        t);
                throw t;
            }

So you can't really register to two eureka servers simultaneously from this code. Unless I missed something.

like image 63
EvilJinious1 Avatar answered Jan 08 '23 18:01

EvilJinious1


Your client application should be provided a list of Eureka URLs. The URLs are comma separated.

like image 26
Robert Greathouse Avatar answered Jan 08 '23 17:01

Robert Greathouse


Yes, as per the documentation, the flow is:

  1. client registers to the first available eureka server
  2. registrant information is replicated between eureka server nodes.

So multiple registration is not only not needed but should be avioded.

like image 41
DJPillowhead Avatar answered Jan 08 '23 16:01

DJPillowhead