Why Is the First Feign Call in a Microservice So Slow?
The article explains that the initial Feign request is slow because Ribbon lazily creates its load‑balancer client and fetches the service list from the registry, and shows how enabling Ribbon's eager‑load mode pre‑warms the client to eliminate the delay.
Feign Call Flow in Microservices
Feign performs remote calls by first consulting a service registry such as Eureka or Nacos. The FeignClient relies on Ribbon for load balancing. Ribbon obtains the list of service instances from the registry, caches it locally, and then the Feign client uses this cached list for subsequent calls.
How Ribbon Performs Load Balancing
Ribbon is configured via RibbonClientConfiguration, which injects a LoadBalancer. The core interface is ILoadBalancer, providing methods to add servers, choose a server, mark a server down, retrieve the server list, and get all servers (healthy and unhealthy).
Ribbon’s default load balancer is ZoneAwareLoadBalancer, which extends DynamicServerListLoadBalancer. Two important methods in DynamicServerListLoadBalancer are enableAndInitLearnNewServersFeature and updateListOfServers.
The enableAndInitLearnNewServersFeature method logs the server‑list updater class and starts it:
LOGGER.info("Using serverListUpdater {}", serverListUpdater.getClass().getSimpleName());
serverListUpdater.start(updateAction);The ServerListUpdater.start implementation creates a dedicated thread to fetch the service list from the registry.
Ribbon Load‑Balancing Strategies
RoundRobinRule– cycles through servers sequentially. WeightedResponseTimeRule – prefers servers with shorter response times. RandomRule – selects a server at random. BestAvailableRule – chooses the server with the fewest active connections. RetryRule – retries failed servers within a timeout. AvailabilityFilteringRule – filters out unhealthy instances. ZoneAvoidanceRule – applies zone‑aware filtering.
Why the First Feign Call Is Slow
Ribbon creates its client only when the first HTTP request occurs. At that moment it must instantiate the client, start the ServerListUpdater, and fetch the service list, which adds extra latency. Subsequent calls reuse the already‑initialized client and cached server list, so they are much faster.
Example controller measuring latency:
@GetMapping("/requestSystem2Api")
public String requestSystem2Api() {
long startTime = System.currentTimeMillis();
R<String> stringR = iTestServiceClient.testRequestMethod();
if (null != stringR) {
log.info("Response: " + stringR.getMsg());
}
long needTime = System.currentTimeMillis() - startTime;
log.info("Call duration: " + needTime);
return "";
}Log output shows a noticeably longer duration on the first invocation because DynamicServerListLoadBalancer loads the service list for the Feign client.
Enabling Ribbon Eager‑Load (Pre‑Warm) Mode
Configure Ribbon to load the service list at application startup:
ribbon:
nacos:
enabled: true
eager-load:
enabled: true
clients: Lxlxxx-system2
ReadTimeout: 10000
ConnectTimeout: 10000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
OkToRetryOnAllOperations: falseWhen the application starts, the specified service ( Lxlxxx-system2) is pre‑loaded, preventing the first‑call timeout.
Conclusion
Ribbon’s eager‑load mode acts as a client‑side pre‑warm step, loading service metadata during startup. This eliminates the extra latency of the first Feign request, which is especially useful when inter‑service calls involve complex business logic that could otherwise cause timeouts.
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.
IT Niuke
Focused on IT technology sharing, original and innovative content. IT Niuke, we grow 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.
