Spring Cloud Eureka Service Discovery: Server and Client Setup with Ribbon and Feign
This article demonstrates how to configure a Spring Cloud Eureka server and multiple client applications, covering dependency inclusion, YAML configuration, service startup, testing, and three consumption methods—DiscoveryClient, Ribbon‑enabled RestTemplate, and Feign—complete with runnable code examples.
The article explains how to use Spring Cloud Eureka for service registration and discovery in a micro‑service architecture, providing step‑by‑step instructions for both the server side and three client consumption patterns.
Service Test Environment
Testing reveals that Netflix Eureka is employed as the service registry.
1. Add Eureka dependencies
<!-- eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>2. Modify configuration files
Server configuration (application.yml)
eureka:
instance:
hostname: eureka9001.com # server instance name
instance-id: eureka9001
client:
register-with-eureka: false # do not register itself
fetch-registry: false # do not fetch other registries
service-url:
defaultZone: http://127.0.0.1:9001Client 1 configuration
server:
port: 8002
spring:
application:
name: licensingservice
eureka:
instance:
instance-id: licensing-service-8002
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:9001/eureka/Client 2 configuration (identical to client 1)
server:
port: 8002
spring:
application:
name: licensingservice
eureka:
instance:
instance-id: licensing-service-8002
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:9001/eureka/3. Start services
Eureka server main class
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerPort9001_App {
public static void main(String[] args) {
SpringApplication.run(EurekaServerPort9001_App.class, args);
}
}Client (license service) main class
@SpringBootApplication
@RefreshScope
@EnableEurekaClient
public class LicenseApplication_8002 {
public static void main(String[] args) {
SpringApplication.run(LicenseApplication_8002.class, args);
}
}4. Test
Open http://127.0.0.1:9001 in a browser to view the registered services and their instances.
Consumer
1. DiscoveryClient method
Enable Eureka client and use DiscoveryClient to obtain the first instance of licensingservice.
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication_7002 {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication_7002.class, args);
}
}
@Component
public class ConsumerDiscoveryClient {
@Autowired
private DiscoveryClient discoveryClient;
public ServiceInstance getServiceInstance() {
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("licensingservice");
if (serviceInstances.isEmpty()) return null;
return serviceInstances.get(0);
}
public String getUrl(String url) {
ServiceInstance serviceInstance = getServiceInstance();
if (serviceInstance == null) throw new RuntimeException("404 ,NOT FOUND");
return String.format(url, serviceInstance.getUri().toString());
}
}
@RestController
@RequestMapping("test")
public class TestController {
private RestTemplate restTemplate = new RestTemplate();
@Autowired
private ConsumerDiscoveryClient consumerDiscoveryClient;
@RequestMapping("/getAllEmp")
public List<Emp> getAllLicense(){
String url = consumerDiscoveryClient.getUrl("%s/test/getAllEmp");
return restTemplate.getForObject(url, List.class);
}
}2. Ribbon‑enabled RestTemplate
Define a load‑balanced RestTemplate bean and a custom round‑robin rule.
// specify load‑balancing algorithm
@Bean
public IRule iRule() {
return new RoundRobinRule();
}
@Bean
@LoadBalanced // creates a RestTemplate that supports Ribbon
public RestTemplate restTemplate() {
return new RestTemplate();
}
@RestController
@RequestMapping("rest")
public class ConsumerRestController {
@Autowired
private RestTemplate restTemplate;
private static final String SERVICE_URL_PREFIX = "http://LICENSINGSERVICE";
@RequestMapping("/getById")
public Emp getById(Long id) {
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
paramMap.add("id", id);
return restTemplate.postForObject(SERVICE_URL_PREFIX + "/test/getById", paramMap, Emp.class);
}
}3. Feign client method
Add the Feign starter dependency and declare a Feign interface.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency> @FeignClient(value = "LICENSINGSERVICE", fallbackFactory = ServiceImp.class)
public interface ServiceInterface {
@RequestMapping("/test/getById")
Emp getById(@RequestParam("id") Long id);
@RequestMapping("/test/getLicenseById")
License getLicenseById(@RequestParam("id") Long id);
@RequestMapping("/test/getAllEmp")
List<Emp> getAllLicense();
}
@Component
public class ServiceImp implements FallbackFactory<ServiceInterface> {
@Override
public ServiceInterface create(Throwable throwable) {
return new ServiceInterface() {
@Override
public Emp getById(Long id) {
Emp emp = new Emp();
emp.setName("i am feign fallback create");
return emp;
}
@Override
public License getLicenseById(Long id) { return null; }
@Override
public List<Emp> getAllLicense() { return null; }
};
}
}
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Consumer_feign_Application_7004 {
public static void main(String[] args) {
SpringApplication.run(Consumer_feign_Application_7004.class, args);
}
}
@RestController
@RequestMapping("rest")
public class ConsumerRestController {
@Autowired
private ServiceInterface serviceInterface;
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getById")
public Emp getById(Long id) {
return serviceInterface.getById(id);
}
}All three consumption approaches are tested: the DiscoveryClient returns the first instance, Ribbon distributes requests round‑robin across instances, and Feign simplifies the client code while providing graceful fallback handling.
Finally, the author invites readers to discuss, ask questions, and join a community group for further learning.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
