{"id":3721,"date":"2025-12-17T09:40:36","date_gmt":"2025-12-17T14:40:36","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3721"},"modified":"2025-12-17T09:40:36","modified_gmt":"2025-12-17T14:40:36","slug":"load-balancing-in-spring-gateway-discovery","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/spring_discovery\/load-balancing-in-spring-gateway-discovery\/","title":{"rendered":"Load Balancing in Spring: Gateway &amp; Discovery"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>Load balancing is crucial in modern applications to distribute traffic across multiple instances of a service, ensuring high availability and fault tolerance. Spring provides robust mechanisms for load balancing, both at the gateway level and through service discovery. This blog post will explore both approaches, highlighting their differences and use cases, particularly how they can work together in a microservice environment. We\u2019ll also delve into how to leverage these mechanisms with OpenFeign clients and RestTemplate, including the use of <code>@LoadBalanced<\/code>.<\/p>\n<h3>Load Balancing with Spring Gateway<\/h3>\n<p>Spring Cloud Gateway acts as an API gateway, routing requests to the appropriate backend services. It leverages Spring Cloud LoadBalancer to distribute traffic among available instances of a service.<\/p>\n<p><strong>How it works:<\/strong><\/p>\n<ol>\n<li><strong>Service Discovery:<\/strong> Spring Gateway integrates with a service registry (e.g., Eureka, Consul) to discover available instances of a service.<\/li>\n<li><strong>Load Balancing:<\/strong> When a request arrives, Spring Gateway uses a load balancing strategy (e.g., round robin, weighted response time) to select an instance of the target service.<\/li>\n<li><strong>Request Routing:<\/strong> The request is then routed to the selected instance.<\/li>\n<\/ol>\n<p><strong>Setup:<\/strong><\/p>\n<ol>\n<li><strong>Dependencies:<\/strong> Include <code>spring-cloud-starter-gateway<\/code> and a service discovery client (e.g., <code>spring-cloud-starter-netflix-eureka-client<\/code>) in your project.<\/li>\n<li><strong>Configuration:<\/strong> Configure routes in <code>application.yml<\/code> or <code>application.properties<\/code> to specify the target service and load balancing strategy.<\/li>\n<\/ol>\n<p><strong>Example:<\/strong><\/p>\n<pre><code class=\"language-yaml\">spring:\n  cloud:\n    gateway:\n      routes:\n      - id: my-service\n        uri: lb:\/\/my-service\n        predicates:\n        - Path=\/my-service\/**\n<\/code><\/pre>\n<p>This configuration routes requests to <code>\/my-service\/**<\/code> to instances of the <code>my-service<\/code> service discovered through the service registry.<\/p>\n<h3>Load Balancing with Spring Discovery<\/h3>\n<p>Spring Cloud Discovery provides client-side load balancing capabilities. Applications can use <code>DiscoveryClient<\/code> or <code>LoadBalancerClient<\/code> to retrieve a list of available service instances and choose one based on a load balancing strategy.<\/p>\n<p><strong>How it works:<\/strong><\/p>\n<ol>\n<li><strong>Service Discovery:<\/strong> The application uses <code>DiscoveryClient<\/code> or <code>LoadBalancerClient<\/code> to fetch instances of the target service from the service registry.<\/li>\n<li><strong>Load Balancing:<\/strong> The client applies a load balancing algorithm (e.g., round robin, random) to select an instance.<\/li>\n<li><strong>Direct Invocation:<\/strong> The application directly invokes the chosen instance.<\/li>\n<\/ol>\n<p><strong>Setup:<\/strong><\/p>\n<ol>\n<li><strong>Dependencies:<\/strong> Include <code>spring-cloud-starter-loadbalancer<\/code> and a service discovery client (e.g., <code>spring-cloud-starter-netflix-eureka-client<\/code>) in your project.<\/li>\n<li><strong>Configuration:<\/strong> Configure the load balancing strategy in <code>application.yml<\/code> or <code>application.properties<\/code>.<\/li>\n<\/ol>\n<p><strong>Example using <code>LoadBalancerClient<\/code>:<\/strong><\/p>\n<pre><code class=\"language-java\">@Autowired\nprivate LoadBalancerClient loadBalancerClient;\n\npublic String callMyService() {\n  ServiceInstance instance = loadBalancerClient.choose(&quot;my-service&quot;);\n  \/\/ Invoke the chosen instance\n  return restTemplate.getForObject(instance.getUri(), String.class);\n}\n<\/code><\/pre>\n<p>This code uses <code>LoadBalancerClient<\/code> to retrieve an instance of <code>my-service<\/code> and directly uses its URI to make a request.<\/p>\n<h3>Combining Gateway and Discovery in a Microservice Environment<\/h3>\n<p>In a microservice architecture, combining Spring Gateway and Spring Discovery offers a powerful solution for managing internal and external traffic.<\/p>\n<p><strong>Scenario:<\/strong><\/p>\n<p>Imagine an e-commerce platform with multiple microservices: <code>product-service<\/code>, <code>order-service<\/code>, and <code>inventory-service<\/code>.<\/p>\n<p><strong>Implementation:<\/strong><\/p>\n<ol>\n<li>\n<p><strong>External API Gateway:<\/strong> Spring Cloud Gateway acts as the entry point for external clients. It handles authentication, authorization, and routes requests to the appropriate microservices (e.g., <code>\/products<\/code> to <code>product-service<\/code>).<\/p>\n<\/li>\n<li>\n<p><strong>Internal Communication:<\/strong> Microservices use Spring Discovery (<code>LoadBalancerClient<\/code>) for internal communication. For example, <code>order-service<\/code> can use <code>LoadBalancerClient<\/code> to call <code>inventory-service<\/code> to check stock availability.<\/p>\n<\/li>\n<\/ol>\n<p><strong>Benefits:<\/strong><\/p>\n<ul>\n<li><strong>Clear separation of concerns:<\/strong> Gateway handles external traffic, while Discovery manages internal communication.<\/li>\n<li><strong>Improved security:<\/strong> Gateway provides a security layer for external access.<\/li>\n<li><strong>Increased resilience:<\/strong> Load balancing at both levels ensures high availability and fault tolerance.<\/li>\n<li><strong>Simplified development:<\/strong> Microservices can focus on their core functionality without worrying about routing or load balancing.<\/li>\n<\/ul>\n<h3>Using Spring Discovery with OpenFeign Clients<\/h3>\n<p>OpenFeign provides a declarative way to create REST clients. You can integrate it with Spring Discovery to leverage load balancing and service discovery for your Feign clients.<\/p>\n<p><strong>How it works:<\/strong><\/p>\n<ol>\n<li><strong>Service Discovery:<\/strong> When creating a Feign client, specify the service name using the <code>name<\/code> attribute in the <code>@FeignClient<\/code> annotation.<\/li>\n<li><strong>Load Balancing:<\/strong> Spring Cloud integrates Ribbon with Feign to automatically load balance requests across available instances of the service.<\/li>\n<\/ol>\n<p><strong>Example:<\/strong><\/p>\n<pre><code class=\"language-java\">@FeignClient(name = &quot;inventory-service&quot;)\npublic interface InventoryClient {\n  \/\/ ... methods to interact with inventory-service ...\n}\n<\/code><\/pre>\n<p>This code defines an <code>InventoryClient<\/code> that will use Ribbon to load balance requests to instances of the <code>inventory-service<\/code> discovered through the service registry.<\/p>\n<h3>Using Spring Discovery with RestTemplate<\/h3>\n<p>RestTemplate can also be used with Spring Discovery for load balanced internal communication between microservices.<\/p>\n<p><strong>How it works:<\/strong><\/p>\n<ol>\n<li><strong><code>@LoadBalanced<\/code> Annotation:<\/strong> Annotate the <code>RestTemplate<\/code> bean with <code>@LoadBalanced<\/code>. This enables Spring Cloud to intercept requests and use Ribbon for client-side load balancing.<\/li>\n<li><strong>Service Name in URL:<\/strong> When making requests with <code>RestTemplate<\/code>, use the service name instead of the actual hostname in the URL (e.g., <code>http:\/\/inventory-service\/inventory\/{productId}<\/code>).<\/li>\n<\/ol>\n<p><strong>Example:<\/strong><\/p>\n<pre><code class=\"language-java\">@Configuration\npublic class AppConfig {\n\n  @Bean\n  @LoadBalanced\n  public RestTemplate restTemplate() {\n    return new RestTemplate();\n  }\n}\n\n@Service\npublic class OrderService {\n\n  @Autowired\n  private RestTemplate restTemplate;\n\n  public void createOrder(Order order) {\n    \/\/ ...\n    Inventory inventory = restTemplate.getForObject(\n        &quot;http:\/\/inventory-service\/inventory\/{productId}&quot;, \n        Inventory.class, order.getProductId());\n    \/\/ ...\n  }\n}\n<\/code><\/pre>\n<p>In this example, <code>@LoadBalanced<\/code> ensures that requests made by the <code>restTemplate<\/code> are load balanced across instances of <code>inventory-service<\/code>.<\/p>\n<h3>Deep Dive into <code>@LoadBalanced<\/code><\/h3>\n<p>The <code>@LoadBalanced<\/code> annotation plays a crucial role in simplifying client-side load balancing with Spring. Let\u2019s break down its significance:<\/p>\n<ul>\n<li><strong>Enabling Load Balancing:<\/strong> This annotation signals to Spring Cloud that the annotated <code>RestTemplate<\/code> should be equipped with load balancing capabilities.<\/li>\n<li><strong>Integration with Ribbon:<\/strong> Behind the scenes, <code>@LoadBalanced<\/code> integrates Ribbon, a client-side load balancer, with the <code>RestTemplate<\/code>. This allows the <code>RestTemplate<\/code> to seamlessly distribute requests across multiple instances of a service.<\/li>\n<li><strong>Service Discovery Integration:<\/strong>  <code>@LoadBalanced<\/code> works in conjunction with a service discovery client (like Eureka or Consul). This allows the <code>RestTemplate<\/code> to dynamically discover available service instances from the registry.<\/li>\n<li><strong>Simplified Configuration:<\/strong> By using <code>@LoadBalanced<\/code>, you avoid manual configuration of load balancing logic. Spring handles the complexities, making your code cleaner and easier to maintain.<\/li>\n<\/ul>\n<p><strong>Key Advantages:<\/strong><\/p>\n<ul>\n<li><strong>Reduced Boilerplate:<\/strong> Eliminates the need to manually retrieve service instances and implement load balancing algorithms.<\/li>\n<li><strong>Improved Readability:<\/strong> Makes your code more concise and focused on business logic.<\/li>\n<li><strong>Enhanced Maintainability:<\/strong> Simplifies configuration and reduces the chance of errors.<\/li>\n<\/ul>\n<p>By combining Spring Gateway, Spring Discovery, OpenFeign, RestTemplate with <code>@LoadBalanced<\/code>, and understanding the power of this annotation, you can build a robust and scalable microservice architecture with efficient load balancing and seamless service communication.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":3710,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[432],"tags":[69,319],"series":[],"class_list":["post-3721","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring_discovery","tag-java-2","tag-spring"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/network-8198745_1280-jpg.avif","jetpack-related-posts":[{"id":3441,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_discovery\/spring-cloud-gateway-with-spring-cloud-discovery\/","url_meta":{"origin":3721,"position":0},"title":"Spring Cloud Gateway with Spring Cloud Discovery","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Cloud Gateway and Spring Cloud Discovery are powerful tools for building microservices architectures. Spring Cloud Gateway acts as an API gateway, routing requests to the appropriate microservices. Spring Cloud Discovery provides a registry for microservices, enabling dynamic service discovery and load balancing. In this comprehensive guide, we'll delve into\u2026","rel":"","context":"In &quot;Spring Discovery&quot;","block_context":{"text":"Spring Discovery","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_discovery\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/trees-2900064_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/trees-2900064_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/trees-2900064_640.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3828,"url":"https:\/\/www.mymiller.name\/wordpress\/spring-gateway\/load-balancing-your-microservices-configuring-spring-cloud-gateway-with-spring-discovery-server\/","url_meta":{"origin":3721,"position":1},"title":"Load Balancing Your Microservices: Configuring Spring Cloud Gateway with Spring Discovery Server","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In a microservices architecture, ensuring high availability and distributing traffic evenly across multiple instances of a service is paramount. Spring Cloud Gateway, when integrated with a Spring Discovery Server (like Netflix Eureka, Consul, or Spring Cloud Service Registry), provides a powerful and straightforward way to achieve client-side load balancing without\u2026","rel":"","context":"In &quot;Spring Gateway&quot;","block_context":{"text":"Spring Gateway","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring-gateway\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/meditation-3814069_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/meditation-3814069_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/meditation-3814069_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/meditation-3814069_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/meditation-3814069_1280.avif 3x"},"classes":[]},{"id":3701,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_discovery\/simplifying-microservices-communication-with-the-java-spring-discovery-client\/","url_meta":{"origin":3721,"position":2},"title":"Simplifying Microservices Communication with the Java Spring Discovery Client","author":"Jeffery Miller","date":"November 24, 2025","format":false,"excerpt":"In the world of microservices, services need to find and communicate with each other dynamically. This is where the Java Spring Discovery Client comes in, offering a streamlined way to interact with a service registry (like Eureka, Consul, or Zookeeper). Let\u2019s explore its core APIs and illustrate their usage with\u2026","rel":"","context":"In &quot;Spring Discovery&quot;","block_context":{"text":"Spring Discovery","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_discovery\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/compass-4713642_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/compass-4713642_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/compass-4713642_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/compass-4713642_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/compass-4713642_1280-jpg.avif 3x"},"classes":[]},{"id":3830,"url":"https:\/\/www.mymiller.name\/wordpress\/spring-gateway\/scaling-the-gatekeeper-load-balancing-multiple-instances-of-spring-cloud-gateway\/","url_meta":{"origin":3721,"position":3},"title":"Scaling the Gatekeeper: Load Balancing Multiple Instances of Spring Cloud Gateway","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"As your microservices ecosystem grows and traffic increases, a single instance of Spring Cloud Gateway might become a bottleneck or a single point of failure. To ensure high availability, fault tolerance, and improved performance, you\u2019ll likely need to run multiple instances of your Spring Cloud Gateway and load balance traffic\u2026","rel":"","context":"In &quot;Spring Gateway&quot;","block_context":{"text":"Spring Gateway","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring-gateway\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3438,"url":"https:\/\/www.mymiller.name\/wordpress\/spring\/architecting-with-spring-and-spring-cloud\/","url_meta":{"origin":3721,"position":4},"title":"Architecting with Spring and Spring Cloud","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Building a Multi-Service Architecture with Spring 3.1.x and Spring Cloud: Unlocking the Power of Microservices In the ever-evolving landscape of software development, microservices have emerged as a powerful architectural paradigm, enabling organizations to build scalable, resilient, and agile applications. Spring, a widely adopted Java framework, provides a comprehensive suite of\u2026","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/field-5236879_640.jpg?fit=640%2C360&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3447,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_discovery\/discovery-first-bootstrap\/","url_meta":{"origin":3721,"position":5},"title":"Discovery First Bootstrap","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In the realm of microservices architecture, effective configuration management is crucial for ensuring the seamless operation and dynamic adaptability of distributed applications. Spring Cloud Config Server and Spring Cloud Discovery Server have emerged as powerful tools for addressing this challenge. While the default \"Config First\" mode offers a straightforward approach,\u2026","rel":"","context":"In &quot;Spring Discovery&quot;","block_context":{"text":"Spring Discovery","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_discovery\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3721"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3721\/revisions"}],"predecessor-version":[{"id":3723,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3721\/revisions\/3723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3710"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3721"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}