Understanding Ribbon Load Balancing and Eager Load Mode in Feign Clients
This article explains how Feign relies on Ribbon for remote calls, details Ribbon's load‑balancing mechanisms, various balancing rules, and demonstrates how enabling Ribbon's eager‑load mode can pre‑warm clients to avoid the latency of the first request.
To understand how Feign performs remote calls, one must know the relationship between the service registry, load balancer, and FeignClient; Feign uses Ribbon for load balancing, which obtains the service list from registries such as Eureka or Nacos, caches it locally, and then the FeignClient invokes the target service.
How Ribbon performs load balancing : Ribbon first retrieves the list of services from the registry (Nacos/Eureka), which is essential for subsequent balancing decisions.
RibbonClientConfiguration : This class configures a LoadBalancer that implements the ILoadBalancer interface, providing methods to add new services, select a service instance, mark servers down, retrieve the full server list, and obtain healthy servers.
ZoneAwareLoadBalancer : The default load balancer, extending DynamicServerListLoadBalancer . Its restOfInit method invokes two important methods— enableAndInitLearnNewServersFeature and updateListOfServers —to manage server discovery and updates.
Example logging code used by Ribbon: LOGGER.info("Using serverListUpdater {}", serverListUpdater.getClass().getSimpleName()); serverListUpdater.start(updateAction);
The ServerListUpdater.start method runs a custom thread to fetch the service list from the registry.
Ribbon load‑balancing strategies : Seven built‑in rules are described—RoundRobinRule, WeightedResponseTimeRule, RandomRule, BestAvailableRule, RetryRule, AvailabilityFilteringRule, and ZoneAvoidanceRule. Custom strategies are beyond the scope of this article.
Ribbon eager‑load (pre‑loading) mode : By default, Ribbon creates a client only when the first HTTP request occurs, causing the first call to be slower due to client initialization. The following controller method demonstrates measuring the latency of the first and subsequent calls:
@GetMapping("/requestSystem2Api") public String requestSystem2Api(){ long startTime = System.currentTimeMillis(); R stringR = iTestServiceClient.testRequestMethod(); if (null != stringR){ log.info("接口返回:"+stringR.getMsg()); } long needTime = System.currentTimeMillis() - startTime; log.info("接口调用需要的时间:"+needTime); return ""; }
Log output shows the first call takes noticeably longer, while the second call is fast because the client has already been loaded.
Enabling eager‑load in the configuration file:
ribbon: nacos: enabled: true # enable Nacos polling eager-load: enabled: true # turn on Ribbon eager‑load to avoid first‑call timeout clients: Lxlxxx-system2 # specify services to pre‑load ReadTimeout: 10000 ConnectTimeout: 10000 MaxAutoRetries: 0 MaxAutoRetriesNextServer: 1 OkToRetryOnAllOperations: false
When the application starts, logs confirm that the specified service is pre‑loaded, preventing the initial timeout.
Summary : Ribbon’s eager‑load mode acts as a client‑side pre‑warming step, loading service metadata at startup to avoid latency spikes during the first inter‑service call, which is especially useful for complex or slow business logic.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.