Skip to content

Service Discovery with Eureka

Wuyi Chen edited this page May 12, 2019 · 5 revisions

Overview

For building up service discovery eco-system, you need to do several things:


Enable Eureka server

build.gradle

dependencies {
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka-server', version: '1.4.4.RELEASE'
}

application.yml

server:
  port: 8761                             # Port for Eureka server

eureka:
  client:
    registerWithEureka: false            # Don't register with Eureka server
    fetchRegistry: false                 # Don't cache registry information locally
  server:
    waitTimeInMsWhenSyncEmpty: 5         # Initial time to wait before server takes requests
  serviceUrl:
    defaultZone: http://localhost:8761

Application Bootstrap Class

@SpringBootApplication
@EnableEurekaServer                      // Enable Eureka server in the Spring service
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

After starting the Eureka server, you can use your web browser to check the detailed information about it: http://localhost:8761


Register services to Eureka server

build.gradle

dependencies {
	compile group: 'org.springframework.cloud',          name: 'spring-cloud-starter-eureka',       version: '1.4.4.RELEASE'      // Includes the Eureka libraries so that the service can register with Eureka

    // omit other dependencies
}

application.yml

spring:
  application:
    name: organizationservice                       # Logical name of the service that will be registered with Eureka

eureka:
  instance:
    preferIpAddress: true                           # Register the IP of the service rather than the server name
  client:
    registerWithEureka: true                        # Register the service with Eureka
    fetchRegistry: true                             # Pull down a local copy of the registry
    serviceUrl:
        defaultZone: http://localhost:8761/eureka/  # Location of the Eureka Service

Application Bootstrap Class

@SpringBootApplication
@EnableEurekaClient                           // Enable Eureka client in the Spring service
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Call the registered services through Eureka server

There are 3 ways to call the registered service:

Spring DiscoveryClient with standard Spring RestTemplate

You can trigger the organization service by Spring DiscoveryClient with standard Spring RestTemplate. There is the client class:

OrganizationDiscoveryClient.java

@Component
public class OrganizationDiscoveryClient {	
    @Autowired
    private DiscoveryClient discoveryClient;         // DiscoveryClient is auto-injected into the class

    public Organization getOrganization(String organizationId) {
        RestTemplate restTemplate = new RestTemplate();
        
        // Gets a list of all the instances of organization service registered with Eureka
        List<ServiceInstance> instances = discoveryClient.getInstances("organizationservice");
        
        // Get the URL of the first instance in the instance list
        String serviceUri = String.format("%s/v1/organizations/%s",instances.get(0).getUri().toString(), organizationId);  // The IP address of the instance you call is NOT abstracted

        // Uses a standard Spring REST Template class to call the service
        ResponseEntity< Organization > restExchange = restTemplate.exchange(serviceUri, HttpMethod.GET, null, Organization.class, organizationId);
        
        return restExchange.getBody();
    }
}

In the application bootstrap class, you need to add the @EnableDiscoveryClient annotation to enable Spring DiscoveryClient

Application Bootstrap Class

@SpringBootApplication
@EnableDiscoveryClient       // Enable Spring DiscoveryClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Ribbon-backed Spring RestTemplate

You can trigger the organization service by Ribbon-backed Spring RestTemplate. There is the client class:

OrganizationRestTemplateClient.java

@Component
public class OrganizationRestTemplateClient {
    @Autowired
    RestTemplate restTemplate;
	
    public Organization getOrganization(String organizationId) {
        ResponseEntity<Organization> restExchange = restTemplate.exchange(
			"http://organizationservice/v1/organizations/{organizationId}",    // The IP address of the instance you call is abstracted
			HttpMethod.GET,
			null, 
			Organization.class, 
			organizationId);
		
        return restExchange.getBody();
    }
}

In the application bootstrap class, you need to add the @LoadBalanced annotation to tells Spring Cloud to create a Ribbon backed RestTemplate class.

Application Bootstrap Class

@SpringBootApplication
public class Application {
    @LoadBalanced                          // This annotation tells Spring Cloud to create a Ribbon backed RestTemplate class.
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Netflix Feign via Ribbon

You can trigger the organization service by Feign client. There is the client class:

OrganizationFeignClient.java

@FeignClient("organizationservice")
public interface OrganizationFeignClient {
    @RequestMapping(method= RequestMethod.GET, value="/v1/organizations/{organizationId}", consumes="application/json")
    Organization getOrganization(@PathVariable("organizationId") String organizationId);
}

In this solution, you just need to define an interface with the @FeignClient annotation. The magic is you don't have to implement the concrete class for this interface, the Spring Cloud framework will dynamically generate a proxy class that will be used to invoke the targeted REST service.

In the application bootstrap class, you need to add the @EnableFeignClients annotation to enable Netflix Feign client.

Application Bootstrap Class

@SpringBootApplication
@EnableFeignClients          // Enable Netflix Feign
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Clone this wiki locally