Implementing Service Consumers with Feign and Load Balancing with Ribbon in Spring Cloud

Feign Service Consumer Implementation

Feign is a declarative web service client that simplifies HTTP API development. It uses annotations to define service interfaces and integrates seamlessly with Spring MVC.

Environment Setup

Required Components:

  • Java 8+
  • Spring Boot 2.1.1+
  • Spring Cloud Finchley+

Dependencies:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>

Service Registry Configuration

application.properties:

spring.application.name=feign-service-registry
server.port=8001
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

Registry Server Class:

@EnableEurekaServer
@SpringBootApplication
public class ServiceRegistryApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceRegistryApplication.class, args);
    }
}

Feign Client Implementation

Consumer Configuration:

spring.application.name=feign-service-consumer
server.port=9002
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

Consumer Application Class:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignConsumerApplication.class, args);
    }
}

Feign Client Interface:

@FeignClient(name = "target-service-provider")
public interface ServiceProxy {
    @RequestMapping(value = "/greet")
    String sendGreeting(@RequestParam(value = "user") String user);
}

Consumer Controller:

@RestController
public class ConsumerEndpoint {
    @Autowired
    ServiceProxy serviceProxy;
    
    @RequestMapping("/greet/{user}")
    public String forwardGreeting(@PathVariable("user") String user) {
        return serviceProxy.sendGreeting(user);
    }
}

Target Service Implementation

Target Service Configuration:

spring.application.name=target-service-provider
server.port=9003
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

Target Service Controller:

@RestController
public class ServiceEndpoint {
    @RequestMapping("/greet")
    public String handleGreeting(@RequestParam String user) {
        return user + ", Welcome!";
    }
}

Ribbon Load Balancer Implementation

Ribbon provides client-side load balancing with configurable algorithms and connection management.

Dependencies:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>

Load Balanced Client Setup

Consumer Configuration:

spring.application.name=ribbon-loadbalancer
server.port=9006
eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/

Service Provider Configurations:

# Provider 1
spring.application.name=balanced-service
server.port=9007

# Provider 2
spring.application.name=balanced-service
server.port=9008

Load Balanced Client Application:

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonClientApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate balancedRestTemplate() {
        return new RestTemplate();
    }
}

Client Controller with Load Balancing:

@RestController
public class LoadBalancedController {
    @Autowired
    RestTemplate restTemplate;
    
    @RequestMapping("/invoke")
    public String callService() {
        return restTemplate.getForObject(
            "http://balanced-service/greet?name=developer", 
            String.class
        );
    }
}

Load Balancing Strategies

Ribbon supports multiple load balancing algorithms:

Strategy Description
RoundRobinRule Sequential rotation through server list
RandomRule Random server selection
WeightedResponseTimeRule Selection based on response time weights
AvailabilityFilteringRule Filters out servers with connectivity issues
ZoneAvoidanceRule Considers zone performance and server availability

Custom Strategy Configuartion:

Method 1 - Properties file:

balanced-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Method 2 - Configuration class:

@Configuration
public class CustomRibbonConfig {
    @Bean
    public IRule customRule() {
        return new RandomRule();
    }
}

@RibbonClient(
    name = "balanced-service", 
    configuration = CustomRibbonConfig.class
)
public class ServiceConfiguration {
}

Manual Server List Configuration:

balanced-service.ribbon.listOfServers=localhost:9007,localhost:9008

Feign with Ribbon Integration

Feign automatically integrates with Ribbon for load balancing when multiple instances of the same service are registered.

Enhanced Feign Client with Load Balancing:

@FeignClient(name = "balanced-service")
public interface LoadBalancedProxy {
    @RequestMapping(value = "/greet")
    String distributedGreeting(@RequestParam(value = "name") String name);
}

Enhanced Controller:

@RestController
public class EnhancedController {
    @Autowired
    LoadBalancedProxy loadBalancedProxy;
    
    @RequestMapping("/distributed/{name}")
    public String loadBalancedCall(@PathVariable("name") String name) {
        return loadBalancedProxy.distributedGreeting(name);
    }
}

Tags: Spring Cloud feign Ribbon Load Balancing microservices

Posted on Tue, 06 Oct 2026 16:53:46 +0000 by thepeccavi