Master Spring Cloud LoadBalancer: From RestTemplate to OpenFeign
This tutorial walks through replacing Ribbon with Spring Cloud LoadBalancer, showing how to configure dependencies, set up RestTemplate and OpenFeign clients, customize caching and request transformation, and verify load‑balanced calls using Nacos as the service registry.
LoadBalancer Introduction
LoadBalancer is the Spring Cloud official load‑balancing component that replaces Ribbon and is largely compatible with Ribbon’s usage.
Usage
Demonstrate basic usage with Nacos as the service registry, using nacos-loadbalancer-service and nacos-user-service for mutual calls.
Load Balancing
Use RestTemplate with @LoadBalanced to achieve client‑side load balancing.
Add the spring-cloud-starter-loadbalancer dependency to the pom.xml of nacos-loadbalancer-service.
Create a Java configuration class that defines a RestTemplate bean annotated with @LoadBalanced.
Configure request timeout in application.yml.
Call the remote service in a controller using the configured RestTemplate.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency> @Configuration
public class RestTemplateConfig {
@Bean
@ConfigurationProperties(prefix = "rest.template.config")
public HttpComponentsClientHttpRequestFactory customHttpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory();
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate(customHttpRequestFactory());
}
} rest:
template:
config:
connectTimeout: 5000
readTimeout: 5000 @RestController
@RequestMapping("/user")
public class UserLoadBalancerController {
@Autowired
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String userServiceUrl;
@GetMapping("/{id}")
public CommonResult getUser(@PathVariable Long id) {
return restTemplate.getForObject(userServiceUrl + "/user/{1}", CommonResult.class, id);
}
// other CRUD methods omitted for brevity
}Declarative Service Call
OpenFeign can be used for declarative calls. Add the spring-cloud-starter-openfeign dependency, define a Feign client interface, and invoke it from a controller.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> @FeignClient(value = "nacos-user-service")
public interface UserService {
@PostMapping("/user/create")
CommonResult create(@RequestBody User user);
@GetMapping("/user/{id}")
CommonResult<User> getUser(@PathVariable Long id);
@GetMapping("/user/getByUsername")
CommonResult<User> getByUsername(@RequestParam String username);
@PostMapping("/user/update")
CommonResult update(@RequestBody User user);
@PostMapping("/user/delete/{id}")
CommonResult delete(@PathVariable Long id);
} @RestController
@RequestMapping("/userFeign")
public class UserFeignController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public CommonResult getUser(@PathVariable Long id) {
return userService.getUser(id);
}
// other methods omitted for brevity
}Feign timeout can be configured in application.yml:
feign:
client:
config:
default: # Feign call timeout configuration
connectTimeout: 5000
readTimeout: 5000Service Instance Cache
LoadBalancer caches service instances locally to improve performance. The default cache TTL is 35 seconds; it can be customized.
spring:
cloud:
loadbalancer:
cache:
enabled: true # enable cache
ttl: 5s # cache time‑to‑live
capacity: 256 # cache sizeHTTP Request Transformation
To add custom headers to each request, implement a LoadBalancerRequestTransformer bean that injects the service instance ID into the X-InstanceId header.
@Configuration
public class LoadBalancerConfig {
@Bean
public LoadBalancerRequestTransformer transformer() {
return new LoadBalancerRequestTransformer() {
@Override
public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) {
return new HttpRequestWrapper(request) {
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = super.getHeaders();
headers.add("X-InstanceId", instance.getInstanceId());
return headers;
}
};
}
};
}
}In the user service, retrieve and log the custom header:
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public CommonResult<User> getUser(@PathVariable Long id) {
User user = userService.getUser(id);
LOGGER.info("User name: {}", user.getUsername());
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String instanceId = request.getHeader("X-InstanceId");
if (StrUtil.isNotEmpty(instanceId)) {
LOGGER.info("Received custom header X-InstanceId={}", instanceId);
}
return new CommonResult<>(user);
}
}Summary
Using Spring Cloud LoadBalancer provides a seamless migration path from Ribbon, with similar configuration and functionality while leveraging modern Spring Cloud features.
Reference
Official documentation: https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer
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.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
