springspring-bootspring-cloudnetflix-eurekaservice-discovery

Spring Cloud Netflix Eureka: Adding server port to virtual hostname in request URL


I am following the 2nd edition book by Magnus Larsson. I am migrating my spring-boot micro-services (run using docker containers) to using Netflix Eureka for service discovery instead of relying on hard-coded IP Addresses and ports. My doubt is from pg. 252.

Here's the situation - there are 2 services X and Y (each running on port 8080 inside their respective containers). X makes a request to Y to fetch some info. Before eureka is introduced, X had Y's host-name and port (which is 8080) hard-coded in its application.yml:

app:
    Y:
       host: Y-host
       port: 8080

So, the URL of a request from X to Y was like http://Y-host:8080

Now eureka is introduced and so, both X and Y will register themselves with eureka using their respective application names app-X and app-Y. Changes are made in the source code of X to use a client-side load-balanced web client to make a request to Y.

The author simply advises to remove the hard-coded config and use the URL http://app-Y while making a request from X to Y (instead of the above mentioned URL).

My question is:

How does X know which port of Y to make a request to? (as Eureka would have served to X only the IP addresses of Y, right?)

And, consequently, had Y exposed multiple ports, how could X have routed different requests to appropriate ports?


Solution

  • How does X know which port of Y to make a request to? (as Eureka would have served to X only the IP addresses of Y, right?)

    As the commentor spencergibb already mentioned eureka registers both the host and the port to be used in the discovery service. Not just the host.

    And, consequently, had Y exposed multiple ports, how could X have routed different requests to appropriate ports?

    For this to have worked, you should have configured different service names for the applications running under the same host name but different ports.

    For example the service Y running under port 8080 offering some APIs could have been declared as spring.application.name=Y-1 while another service under the same host offering some different APIs under another port should have been declared as a different service e.g. spring.application.name=Y-2 in it's own spring boot configurations used to be registered in the eureka server.

    Then with:

    @FeignClient(name = "Y-1")
    public interface ServiceY1Client {
    
    ....
    
    }
    
    
    @FeignClient(name = "Y-2")
        public interface ServiceY2Client {
    
        ....
    
    }
    

    the service which needs to identify these running services would be able to fetch the necessary host and port for service Y-1 and service Y-2 and make the requested calls.