Cloud Native 10 min read

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.

macrozheng
macrozheng
macrozheng
Master Spring Cloud LoadBalancer: From RestTemplate to OpenFeign

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: 5000

Service 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 size

HTTP 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

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MicroservicesNacosresttemplateOpenFeignloadbalancerspring-cloud
macrozheng
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.