Printing is unavailable

This course is licensed for personal online viewing only.

Public preview • CL-P000000-C41-L1821-51C7CC36

Home Dashboard
Chapter 465 · Module 3 — Service Discovery and Load Balancing

Client-Side Load Balancing with Spring Cloud LoadBalancer

6,586
words
37
min read
3
tools

1. Learning Outcomes#

इस chapter के बाद आप:

  • Client-Side Load Balancing का वास्तविक मतलब समझ पाएँगे।
  • Service Discovery और Load Balancing के बीच का संबंध समझ पाएँगे।
  • spring-cloud-starter-loadbalancer dependency का purpose समझ पाएँगे।
  • logical service name जैसे inventory-service से multiple instances resolve करना समझ पाएँगे।
  • ServiceInstanceListSupplier की भूमिका समझ पाएँगे।
  • default Round-Robin और Random selection strategy में अंतर समझ पाएँगे।
  • @LoadBalanced के साथ RestClient.Builder और WebClient.Builder configure कर पाएँगे।
  • Spring HTTP Service Clients को load-balanced calls के लिए use करना समझ पाएँगे।
  • OpenFeign के साथ Spring Cloud LoadBalancer का संबंध समझ पाएँगे।
  • multiple service instances पर requests distribute हो रही हैं या नहीं, यह verify कर पाएँगे।
  • LoadBalancer caching का purpose और double-caching problem समझ पाएँगे।
  • Netflix Ribbon और Spring Cloud LoadBalancer के बीच modern migration direction समझ पाएँगे।

2. Definition#

English Definition

Client-side load balancing is a technique in which the calling application obtains a list of available service instances and selects one instance locally before sending the request.

सरल हिंदी में, मान लीजिए order-service को inventory-service से data चाहिए।

लेकिन production environment में inventory-service की केवल एक copy नहीं होती। उसकी कई running instances हो सकती हैं:

  • inventory-service on port 8081
  • inventory-service on port 8082
  • inventory-service on port 8083

अब order-service को हर बार manually यह नहीं बताया जाना चाहिए कि कौन-सा port call करना है।

Client-side load balancing में calling service के अंदर मौजूद load-balancing mechanism available instances की list लेता है, उनमें से एक instance चुनता है, और request उस selected instance को भेजता है।

यही काम Spring ecosystem में Spring Cloud LoadBalancer कर सकता है।

Key Idea

Service Discovery बताता है कि service की कौन-कौन सी instances available हैं। Load Balancer उन available instances में से एक instance चुनता है।


3. समस्या क्या है जिसे Load Balancing solve करता है?#

मान लीजिए हमारे पास केवल यह URL है:

http://localhost:8081/inventory/products/101

यह URL एक particular machine और port को point कर रहा है।

अगर 8081 वाली instance down हो गई, तो request fail हो जाएगी।

अब हमने दूसरी instance start की:

http://localhost:8082

और तीसरी:

http://localhost:8083

लेकिन application code में अभी भी 8081 hardcoded है।

इसलिए केवल multiple instances start कर देना पर्याप्त नहीं है।

हमें ऐसा mechanism चाहिए जो:

  1. available instances खोजे,
  2. उनमें से एक healthy candidate चुने,
  3. request उस instance को भेजे,
  4. अगली requests को अन्य instances में distribute कर सके।

यहीं Service Discovery और Client-Side Load Balancing साथ काम करते हैं।


4. Service Discovery और Load Balancing एक ही चीज़ नहीं हैं#

Beginners अक्सर इन दोनों concepts को एक समझ लेते हैं।

इनकी responsibilities अलग हैं।

Responsibility Service Discovery Load Balancer
Service कहाँ चल रही है पता करना Yes No
Available instances की list देना Yes Uses this list
एक instance select करना No Yes
Request distribution strategy apply करना No Yes
Logical service name resolve करने में मदद Yes Yes, discovery data के साथ
Round-Robin या Random selection No Yes

उदाहरण के लिए Service Registry में यह information हो सकती है:

Service ID Host Port
inventory-service host-a 8081
inventory-service host-b 8082
inventory-service host-c 8083

Calling application केवल यह कहती है:

http://inventory-service/inventory/products/101

यहाँ inventory-service physical hostname की तरह treat नहीं किया जाना चाहिए।

यह एक logical service name है।

Load-balanced HTTP client इस logical name को intercept करता है, discovery information से available instances लेता है और उनमें से एक actual destination चुनता है।


5. पूरा request flow visually समझें#

नीचे का flow ध्यान से देखें।

Visual Diagram80%

Rendering diagram…

इस diagram में सबसे important observation यह है कि application सीधे पहले से fixed 8081 या 8082 select नहीं कर रही।

Application logical service name use करती है।

Spring Cloud LoadBalancer discovery से मिली candidate list में से actual destination चुनता है।

Remember

Discovery का काम candidate instances देना है। Selection strategy का काम LoadBalancer का है।


6. Server-Side और Client-Side Load Balancing में basic difference#

दोनों approaches का उद्देश्य traffic distribute करना है, लेकिन instance selection कहाँ होता है यह अलग है।

Server-Side Load Balancing#

इस model में application request किसी central component को भेजती है।

उदाहरण:

Client → Load Balancer / Reverse Proxy → Service Instance

Central load balancer actual backend चुनता है।

Client-Side Load Balancing#

इस model में calling application के पास load-balancing logic होता है।

Flow:

Caller → discover instances → choose instance → call selected instance

Spring Cloud LoadBalancer इसी client-side model का implementation देता है।

Microservice-to-microservice communication में यह बहुत useful है क्योंकि caller logical service ID के आधार पर request कर सकता है।


7. Spring Cloud LoadBalancer dependency जोड़ना#

Maven project में Spring Cloud dependency management पहले से configured होने पर LoadBalancer starter इस प्रकार add किया जा सकता है:

XML
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

सामान्यतः Spring Cloud BOM dependency versions manage करता है, इसलिए individual Spring Cloud starter के लिए manually arbitrary version लिखना avoid करना चाहिए।

Gradle में equivalent dependency:

GRADLE
implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'

यह starter Spring Cloud LoadBalancer infrastructure उपलब्ध कराता है।

Common Mistake

केवल Discovery Client dependency add कर देने से हर HTTP client automatically load-balanced नहीं बन जाता। जिस HTTP client को logical service names के साथ use करना है, उसे appropriate LoadBalancer integration चाहिए।


8. Example architecture#

हम आगे इस simple architecture को use करेंगे:

  • discovery-server
  • order-service
  • inventory-service instance A
  • inventory-service instance B

दोनों inventory instances का application name समान होगा:

YAML
spring:
  application:
    name: inventory-service

यही logical service ID discovery registry में दिखाई देगा।

मान लें पहली instance port 8081 पर और दूसरी 8082 पर चलती है।

दोनों का logical name फिर भी:

inventory-service

रहेगा।

यही microservices architecture का बड़ा फायदा है।

Caller को physical ports की list maintain नहीं करनी पड़ती।


9. Multiple instances को पहचानने के लिए छोटा endpoint#

Testing के समय हमें यह पता होना चाहिए कि response किस instance से आया।

इसके लिए inventory-service में एक simple property रख सकते हैं।

JAVA
@RestController
@RequestMapping("/inventory")
public class InventoryController {

    private final String instanceId;

    public InventoryController(
            @Value("${app.instance-id}") String instanceId) {
        this.instanceId = instanceId;
    }

    @GetMapping("/instance")
    public String instance() {
        return instanceId;
    }
}

पहली instance को इस तरह run किया जा सकता है:

BASH
java -jar inventory-service.jar --server.port=8081 --app.instance-id=inventory-1

दूसरी instance:

BASH
java -jar inventory-service.jar --server.port=8082 --app.instance-id=inventory-2

दोनों instances discovery registry में inventory-service नाम से register होनी चाहिए।

अब हमारे पास logical service के पीछे दो physical destinations हैं।


10. Logical Service Name क्यों important है?#

Hardcoded call ऐसा दिख सकता है:

http://localhost:8081/inventory/instance

इसमें caller स्वयं physical address जानता है।

Load-balanced call ऐसा दिखेगा:

http://inventory-service/inventory/instance

अब caller केवल service identity जानता है।

Physical destination runtime पर resolve होगी।

यही distinction microservices में बहुत important है।

Key Idea

inventory-service application code में stable logical identity है, जबकि host-a:8081, host-b:8082 जैसी addresses runtime infrastructure details हैं।


11. अगर @LoadBalanced नहीं लगाया तो क्या होगा?#

मान लीजिए आपने normal RestClient से request की:

http://inventory-service/inventory/instance

Normal HTTP client इसे ordinary hostname समझ सकता है।

फिर operating system या DNS से inventory-service resolve करने की कोशिश होगी।

अगर वह DNS hostname नहीं है, तो request fail हो सकती है।

@LoadBalanced integration HTTP client को Spring Cloud LoadBalancer के साथ जोड़ती है।

तब inventory-service को physical DNS host की बजाय service ID के रूप में resolve किया जा सकता है।


12. Modern synchronous client: RestClient के साथ @LoadBalanced#

Modern synchronous Spring HTTP calls के लिए RestClient एक important option है।

पहले load-balanced builder बनाइए:

JAVA
@Configuration
public class HttpClientConfiguration {

    @Bean
    @LoadBalanced
    RestClient.Builder loadBalancedRestClientBuilder() {
        return RestClient.builder();
    }
}

यहाँ @LoadBalanced सबसे important annotation है।

अब इस builder से बनाई गई client logical service name के साथ request कर सकती है।

JAVA
@Service
public class InventoryClient {

    private final RestClient restClient;

    public InventoryClient(
            @LoadBalanced RestClient.Builder builder) {

        this.restClient = builder
                .baseUrl("http://inventory-service")
                .build();
    }

    public String getCurrentInstance() {
        return restClient
                .get()
                .uri("/inventory/instance")
                .retrieve()
                .body(String.class);
    }
}

यहाँ ध्यान दें कि code में 8081 या 8082 कहीं नहीं है।

Base URL है:

http://inventory-service

Spring Cloud LoadBalancer runtime पर actual instance choose करेगा।


13. Caller endpoint बनाकर testing करना#

order-service में एक endpoint बना सकते हैं:

JAVA
@RestController
@RequestMapping("/demo")
public class LoadBalancerDemoController {

    private final InventoryClient inventoryClient;

    public LoadBalancerDemoController(
            InventoryClient inventoryClient) {
        this.inventoryClient = inventoryClient;
    }

    @GetMapping("/instance")
    public String currentInstance() {
        return inventoryClient.getCurrentInstance();
    }
}

अब repeatedly call करें:

BASH
curl http://localhost:8080/demo/instance

अगर दोनों inventory instances correctly registered और healthy हैं, तो responses अलग-अलग instances से आ सकते हैं।

Round-Robin configuration में conceptual observation ऐसा हो सकता है:

Request Selected Instance
1 inventory-1
2 inventory-2
3 inventory-1
4 inventory-2

Exact first instance अलग हो सकती है।

Important point यह है कि stable two-instance setup में Round-Robin requests को क्रम से rotate करता है।


14. WebClient के साथ @LoadBalanced#

Reactive applications में WebClient commonly use होता है।

Configuration:

JAVA
@Configuration
public class ReactiveHttpClientConfiguration {

    @Bean
    @LoadBalanced
    WebClient.Builder loadBalancedWebClientBuilder() {
        return WebClient.builder();
    }
}

Client:

JAVA
@Service
public class ReactiveInventoryClient {

    private final WebClient webClient;

    public ReactiveInventoryClient(
            @LoadBalanced WebClient.Builder builder) {

        this.webClient = builder
                .baseUrl("http://inventory-service")
                .build();
    }

    public Mono<String> getCurrentInstance() {
        return webClient
                .get()
                .uri("/inventory/instance")
                .retrieve()
                .bodyToMono(String.class);
    }
}

Concept वही है।

Difference HTTP programming model में है।

RestClient synchronous/blocking style के लिए useful है।

WebClient reactive/non-blocking scenarios के लिए useful है।

Load-balancing perspective से दोनों logical service ID use कर सकते हैं।


15. RestTemplate का क्या?#

बहुत से existing Spring projects में RestTemplate अभी भी दिखाई देगा।

उसके साथ भी @LoadBalanced integration historically use होती रही है।

लेकिन नए code में current Spring direction के अनुसार synchronous HTTP access के लिए RestClient और reactive access के लिए WebClient अधिक relevant choices हैं।

इस chapter का मुख्य concept किसी एक HTTP client पर depend नहीं है।

Concept है:

logical service name + discovery + instance selection + request execution


16. ServiceInstanceListSupplier क्या है?#

English Definition

ServiceInstanceListSupplier provides the list of service instances that Spring Cloud LoadBalancer can consider when selecting a destination for a service request.

सरल हिंदी में, LoadBalancer को instance select करने से पहले यह पता होना चाहिए कि candidates कौन-कौन हैं।

उदाहरण:

Candidate Host Port
Instance A host-a 8081
Instance B host-b 8082
Instance C host-c 8083

ServiceInstanceListSupplier का काम ऐसे candidate instances उपलब्ध कराना है।

फिर LoadBalancer algorithm उस list में से एक instance choose करता है।

इसलिए mental model रखें:

Supplier gives candidates.
LoadBalancer chooses one candidate.


17. ServiceInstanceListSupplier और Service Discovery का संबंध#

Discovery-backed setup में supplier discovery client से instances retrieve कर सकता है।

Conceptual flow:

Visual Diagram80%

Rendering diagram…

यहाँ learner को तीन layers अलग-अलग समझनी चाहिए:

  1. Service Registry service registrations रखती है।
  2. ServiceInstanceListSupplier candidate list उपलब्ध कराता है।
  3. LoadBalancer candidate list में से destination चुनता है।

इन तीनों responsibilities को mix करने से architecture समझना कठिन हो जाता है।


18. Custom ServiceInstanceListSupplier configuration#

Default behavior काफी applications के लिए पर्याप्त हो सकता है।

लेकिन Spring Cloud LoadBalancer supplier chain customize करने की सुविधा भी देता है।

उदाहरण:

JAVA
public class InventoryInstanceSupplierConfiguration {

    @Bean
    ServiceInstanceListSupplier serviceInstanceListSupplier(
            ConfigurableApplicationContext context) {

        return ServiceInstanceListSupplier.builder()
                .withDiscoveryClient()
                .withCaching()
                .build(context);
    }
}

फिर इसे specific service के लिए attach किया जा सकता है:

JAVA
@Configuration
@LoadBalancerClient(
        name = "inventory-service",
        configuration = InventoryInstanceSupplierConfiguration.class)
public class InventoryLoadBalancerClientConfiguration {
}

यह configuration बताती है कि inventory-service के लिए instance list discovery से आए और supplier chain caching भी use करे।

Note

@LoadBalancerClient में pass की गई custom configuration class को normal component scanning से accidentally global configuration की तरह register नहीं करना चाहिए। Per-client configuration और main application configuration को अलग रखना बेहतर है।


19. Instance selection कहाँ होता है?#

एक बार candidate instances मिल जाएँ, अगला question होता है:

कौन-सी instance चुनी जाए?

Spring Cloud LoadBalancer selection के लिए ReactorLoadBalancer<ServiceInstance> abstraction use करता है।

Common built-in strategies में शामिल हैं:

  • Round-Robin
  • Random

इन दोनों का behavior अलग है।


20. Round-Robin strategy#

Current default LoadBalancer implementation RoundRobinLoadBalancer है।

Round-Robin का basic idea है:

एक request instance A को।

अगली request instance B को।

अगली request instance C को।

फिर वापस instance A।

तीन instances के लिए conceptual rotation:

Visual Diagram80%

Rendering diagram…

यह deterministic rotation जैसा behavior देता है।

लेकिन real production traffic में availability changes, retries, instance refresh, concurrent requests और other factors observed sequence को प्रभावित कर सकते हैं।

इसलिए Round-Robin का मतलब यह नहीं है कि हर production log हमेशा perfect A-B-C-A-B-C pattern ही दिखाएगा।


21. Round-Robin कब useful है?#

जब instances लगभग समान capacity की हों और simple fair distribution चाहिए, तब Round-Robin अच्छा default है।

उदाहरण:

  • सभी instances समान CPU/memory configuration पर चल रही हैं।
  • सभी same application version run कर रही हैं।
  • किसी particular instance को ज्यादा preference नहीं देनी।

इस स्थिति में basic rotation समझना और troubleshoot करना आसान होता है।


22. Random strategy#

Random strategy available candidates में से randomly एक instance चुनती है।

तीन instances होने पर successive selection ऐसा हो सकता है:

Request Possible Selection
1 Instance B
2 Instance A
3 Instance B
4 Instance C
5 Instance C

इसमें strict rotation नहीं होती।

Short sample में एक instance कई बार select हो सकती है।

इसका मतलब algorithm broken नहीं है।

Random selection probability-based है।

Common Mistake

पाँच requests में exact equal distribution न मिलने पर Random strategy को faulty मत मानिए। Random selection small sample में naturally uneven दिखाई दे सकती है।


23. RandomLoadBalancer configure करना#

Specific service के लिए custom LoadBalancer configuration बनाई जा सकती है।

JAVA
public class RandomLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {

        String serviceId = environment.getProperty(
                LoadBalancerClientFactory.PROPERTY_NAME);

        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(
                        serviceId,
                        ServiceInstanceListSupplier.class),
                serviceId);
    }
}

इसे inventory-service के साथ associate करें:

JAVA
@Configuration
@LoadBalancerClient(
        name = "inventory-service",
        configuration = RandomLoadBalancerConfiguration.class)
public class InventoryRandomLoadBalancerClientConfiguration {
}

अब उस service के लिए RandomLoadBalancer use किया जा सकता है।

Remember

Algorithm बदलने से Service Discovery का role नहीं बदलता। Discovery अभी भी instances देती है; केवल candidate selection strategy बदलती है।


24. Round-Robin vs Random#

Point Round-Robin Random
Selection style Rotating Random
Default Spring Cloud LoadBalancer strategy Yes No
Short-run distribution More predictable Uneven हो सकती है
Mental model Next candidate Random candidate
Simple debugging Easier थोड़ा less predictable

Production architecture में strategy selection business requirements पर depend कर सकती है।

इस chapter में मुख्य उद्देश्य built-in default और alternate strategy का mental model समझना है।


25. @LoadBalanced actually क्या करता है?#

@LoadBalanced केवल decorative annotation नहीं है।

यह Spring को बताता है कि इस HTTP client builder को load-balancing infrastructure के साथ customize किया जाना है।

इसके बाद logical URI:

http://inventory-service/inventory/instance

का host portion service ID की तरह use हो सकता है।

High-level flow:

Visual Diagram80%

Rendering diagram…

Conceptually physical URI runtime पर ऐसा बन सकता है:

http://host-b:8082/inventory/instance

Application code को उस physical address को manually construct करने की आवश्यकता नहीं पड़ती।


26. @LoadBalanced के साथ multiple builders#

कभी application को दो प्रकार के HTTP clients चाहिए:

  1. internal microservice calls के लिए load-balanced client
  2. external APIs के लिए normal client

ऐसी स्थिति में beans को clearly distinguish करना अच्छा है।

JAVA
@Configuration
public class RestClientConfiguration {

    @Bean
    @LoadBalanced
    RestClient.Builder internalServiceClient() {
        return RestClient.builder();
    }

    @Bean
    @Primary
    RestClient.Builder externalApiClient() {
        return RestClient.builder();
    }
}

अब internal service client logical service names use कर सकता है।

External client ordinary public URLs के लिए use किया जा सकता है।

Common Mistake

हर RestClient.Builder को blindly @LoadBalanced मत बनाइए। External URL calls और service-discovery-based internal calls की responsibility अलग रखना cleaner design है।


27. Spring HTTP Service Clients क्या हैं?#

Spring HTTP Service Clients annotated Java interfaces के माध्यम से remote HTTP API call करने का declarative तरीका देते हैं।

उदाहरण interface:

JAVA
@HttpExchange("/inventory")
public interface InventoryHttpClient {

    @GetExchange("/instance")
    String getCurrentInstance();
}

Application business code को low-level request construction repeatedly लिखने की आवश्यकता कम हो जाती है।

Conceptually यह interface remote HTTP service का contract represent करता है।


28. HTTP Service Client को LoadBalancer से जोड़ना#

Current Spring Cloud LoadBalancer versions में Spring HTTP Service Client groups के लिए direct integration उपलब्ध है।

एक group define किया जा सकता है:

JAVA
@SpringBootApplication
@ImportHttpServices(
        group = "inventory-service",
        types = InventoryHttpClient.class)
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(
                OrderServiceApplication.class,
                args);
    }
}

Spring Cloud LoadBalancer 5.0+ integration में, जब HTTP Service Client group का explicit physical base-url नहीं दिया गया हो, group name service ID के रूप में use किया जा सकता है।

इस example में logical service ID है:

inventory-service

Load-balanced resolution तब available discovery instances के against हो सकती है।


29. lb scheme के साथ HTTP Service Client#

Current integration lb scheme भी support करती है।

Conceptual configuration:

YAML
spring:
  http:
    serviceclient:
      inventory:
        base-url: lb://inventory-service

यह स्पष्ट करता है कि destination load-balanced service ID है।

दूसरी ओर अगर आप physical URL set कर दें:

YAML
spring:
  http:
    serviceclient:
      inventory:
        base-url: http://localhost:8081

तो आपने destination पहले से fixed कर दी।

ऐसे physical base URL के साथ discovery-based instance selection का उद्देश्य समाप्त हो जाता है।

Key Idea

Declarative client technology बदल सकती है, लेकिन वही principle रहता है: logical service identity रखें और physical instance selection infrastructure को करने दें।


30. OpenFeign के साथ Load Balancing#

Spring Cloud OpenFeign declarative REST client approach है।

Basic Feign client:

JAVA
@FeignClient(name = "inventory-service")
public interface InventoryFeignClient {

    @GetMapping("/inventory/instance")
    String getCurrentInstance();
}

यहाँ name = "inventory-service" बहुत important है।

अगर Spring Cloud LoadBalancer classpath पर मौजूद है, Feign service-name-based calls को LoadBalancer के साथ integrate कर सकता है।

OpenFeign starter use करने वाले project में LoadBalancer dependency optional होती है, इसलिए load balancing चाहिए तो project में LoadBalancer starter available होना चाहिए।

XML
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

Application में Feign scanning enable की जा सकती है:

JAVA
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(
                OrderServiceApplication.class,
                args);
    }
}

अब Feign interface logical service ID के आधार पर remote call कर सकती है।


31. Feign में hardcoded URL का effect#

यह declarative-looking configuration है:

JAVA
@FeignClient(
        name = "inventory-service",
        url = "http://localhost:8081")
public interface InventoryFeignClient {

    @GetMapping("/inventory/instance")
    String getCurrentInstance();
}

लेकिन यहाँ actual destination hardcoded है।

इसलिए caller service discovery से multiple instances choose करने वाला architecture use नहीं कर रही।

Load-balanced discovery-based call के लिए service name को logical destination के रूप में use करना चाहिए।

Common Mistake

@FeignClient use करना अपने आप यह guarantee नहीं करता कि call multiple discovered instances में distribute होगी। Configuration में fixed physical URL देने से instance selection bypass हो सकता है।


32. OpenFeign का current architectural position#

OpenFeign existing applications में widely used हो सकता है और Spring Cloud LoadBalancer के साथ integrate करता है।

लेकिन current Spring Cloud documentation OpenFeign को feature-complete मानती है और newer development के लिए Spring HTTP Service Clients की ओर migration direction suggest करती है।

इसलिए job-ready developer को दोनों समझने चाहिए:

  • existing systems में OpenFeign
  • modern Spring HTTP Service Clients
  • दोनों के नीचे service discovery और load balancing का common concept

33. Request distribution verify कैसे करें?#

Load balancing configure करने के बाद केवल application start हो गई, इसलिए feature working है, ऐसा assume नहीं करना चाहिए।

Verification के लिए कुछ concrete checks करें।

Check 1 — Registry में multiple instances#

Service Registry में inventory-service की कम से कम दो healthy instances दिखनी चाहिए।

उदाहरण:

Instance Port Status
inventory-1 8081 UP
inventory-2 8082 UP

अगर केवल एक instance available है, LoadBalancer के पास selection के लिए दूसरा candidate ही नहीं है।


Check 2 — Caller physical port use नहीं कर रहा#

Caller URL:

http://inventory-service/inventory/instance

जैसा होना चाहिए।

अगर code में:

http://localhost:8081

लिखा है, तो testing वास्तव में client-side load balancing test नहीं कर रही।


Check 3 — Multiple requests भेजें#

BASH
curl -s http://localhost:8080/demo/instance
curl -s http://localhost:8080/demo/instance
curl -s http://localhost:8080/demo/instance
curl -s http://localhost:8080/demo/instance

Round-Robin setup में responses दोनों instances से आने चाहिए।

उदाहरण observation:

Call Response
1 inventory-1
2 inventory-2
3 inventory-1
4 inventory-2

फिर से याद रखें कि exact first selected instance fixed मानना आवश्यक नहीं है।


Check 4 — एक instance stop करें#

मान लें inventory-2 को stop किया।

Discovery registry से उसकी availability हटने के बाद LoadBalancer candidate list में remaining instance use करेगा।

अगर caller फिर भी stopped instance को बहुत देर तक use करने की कोशिश कर रहा है, तब discovery refresh, caching और health information inspect करनी चाहिए।

यहीं caching concept practical बनता है।


34. LoadBalancer caching क्यों चाहिए?#

हर request से पहले remote discovery registry call करना inefficient हो सकता है।

Flow ऐसा हो:

request → discovery server → instance list → choose instance

अगर traffic बहुत ज्यादा है, हर request पर registry lookup unnecessary overhead create कर सकता है।

Caching का idea है कि recently retrieved service instance list कुछ समय locally reuse की जाए।

Visual Diagram80%

Rendering diagram…

Cache hit होने पर remote lookup avoid हो सकता है।

इससे discovery infrastructure पर unnecessary load कम हो सकता है।


35. Spring Cloud LoadBalancer cache implementations#

Spring Cloud LoadBalancer caching support देता है।

अगर Caffeine classpath पर उपलब्ध है, Caffeine-backed cache use की जा सकती है।

अगर Caffeine उपलब्ध नहीं है, starter के साथ default LoadBalancer cache implementation उपलब्ध होती है।

Current standard configuration properties में cache enablement, TTL और capacity configure किए जा सकते हैं।

YAML
spring:
  cloud:
    loadbalancer:
      cache:
        enabled: true
        ttl: 35s
        capacity: 256

ttl का अर्थ है cache entry कितनी देर बाद expire होगी।

capacity cache की initial capacity से संबंधित setting है।

Note

Defaults framework version के साथ बदल सकते हैं। Production configuration को अपने Spring Cloud release और operational requirements के अनुसार verify करना चाहिए।


36. Cache हमेशा बेहतर नहीं होता#

Caching performance improve कर सकती है, लेकिन stale information का risk भी introduce करती है।

मान लें:

  1. cache में दो instances हैं,
  2. एक instance remove हो गई,
  3. cache अभी expire नहीं हुई।

कुछ समय तक cached list old state represent कर सकती है।

इसलिए cache freshness और registry lookup frequency के बीच trade-off होता है।


37. Double caching problem#

कुछ Service Discovery implementations स्वयं भी caching करती हैं।

उदाहरण के लिए discovery client local registry information cache कर सकता है।

अगर उसके ऊपर Spring Cloud LoadBalancer cache भी same data cache करे, तो दो cache layers बन सकती हैं।

Conceptual flow:

LoadBalancer Cache → Discovery Client Cache → Registry

इससे updates visible होने में अतिरिक्त delay हो सकता है।

Current Spring Cloud guidance के अनुसार अगर underlying DiscoveryClient already effectively caching कर रहा है, तो LoadBalancer-level caching disable करना कुछ environments में sensible हो सकता है।

उदाहरण:

YAML
spring:
  cloud:
    loadbalancer:
      cache:
        enabled: false

यह blindly हर project में apply नहीं करना चाहिए।

पहले समझें कि आपका discovery implementation क्या cache कर रहा है।

Warning

Production issue देखकर random cache settings बदलना सही debugging approach नहीं है। पहले registry state, discovery-client state, LoadBalancer candidate list और cache behavior अलग-अलग verify करें।


38. ServiceInstanceListSupplier chain को mental model की तरह समझें#

Supplier architecture को filter pipeline की तरह imagine कर सकते हैं।

Base supplier instances ला सकता है।

उसके बाद caching या अन्य filtering/decorating supplier candidates को process कर सकते हैं।

सरल mental model:

Visual Diagram80%

Rendering diagram…

इस chapter में हमें supplier chain की सभी advanced strategies memorize नहीं करनी।

Important understanding यह है:

  • candidate list कहाँ से आती है,
  • optional caching कहाँ हो सकती है,
  • algorithm selection उसके बाद होती है।

39. Failure case: No available instance#

अगर discovery से inventory-service के लिए कोई available instance नहीं मिलता, तो LoadBalancer magic से service create नहीं कर सकता।

Request fail होगी क्योंकि destination उपलब्ध नहीं है।

इसलिए Load Balancer:

  • service discovery का replacement नहीं है,
  • service health का replacement नहीं है,
  • missing service instance का replacement नहीं है।

यह available candidates में से selection करता है।

Remember

Zero candidates in means zero candidates out. LoadBalancer केवल available information पर काम कर सकता है।


40. Failure case: Service name mismatch#

Provider:

YAML
spring:
  application:
    name: inventory-service

लेकिन caller:

http://inventoryservice/...

use कर रहा है।

ये दो अलग service IDs हैं।

Logical service name exact matching important है।

Naming inconsistency बहुत common configuration bug है।


41. Failure case: केवल एक instance register हुई#

Developer दो application windows open करता है, लेकिन दोनों same port use करने की कोशिश करती हैं।

दूसरी application start ही नहीं होती।

Registry में केवल एक instance रहती है।

फिर repeated requests हमेशा same instance पर जाती हैं।

Developer सोच सकता है LoadBalancer काम नहीं कर रहा।

असल problem यह है कि candidate list में केवल एक instance है।

Debugging में सबसे पहले candidate count verify करना चाहिए।


42. Failure case: @LoadBalanced bean use ही नहीं हुआ#

आपने यह bean बनाया:

JAVA
@Bean
@LoadBalanced
RestClient.Builder loadBalancedBuilder() {
    return RestClient.builder();
}

लेकिन client class में directly यह कर दिया:

JAVA
RestClient restClient = RestClient.create();

अब आपने load-balanced builder bypass कर दिया।

इसलिए logical service ID resolution expected तरीके से नहीं होगी।

Configuration बनाना और actual request path में उसी configured bean को use करना दोनों आवश्यक हैं।


43. Real Project Mental Model#

Production microservice communication को इस sequence में याद रखें:

Visual Diagram80%

Rendering diagram…

इस flow को समझने के बाद RestClient, WebClient, OpenFeign या HTTP Service Client केवल integration styles बन जाते हैं।

Core architecture समान रहती है।


44. Netflix Ribbon कहाँ fit होता था?#

Older Spring Cloud architectures में Netflix Ribbon popular client-side load balancer था।

Historical code और interview questions में Ribbon आज भी दिखाई दे सकता है।

लेकिन Ribbon maintenance mode में गया और modern Spring Cloud ने Spring Cloud LoadBalancer को replacement direction के रूप में अपनाया।

इसलिए new Spring Cloud project में mental model यह होना चाहिए:

Legacy: Netflix Ribbon
Modern: Spring Cloud LoadBalancer

Old tutorials देखकर नई application में Ribbon dependency add करना सही approach नहीं है।

Interview Point

Ribbon का concept जानना useful है क्योंकि legacy projects और old interview material में उसका नाम आता है। लेकिन modern implementation choice Spring Cloud LoadBalancer है।


45. Spring Cloud LoadBalancer को modern क्यों माना जाता है?#

यह Spring Cloud ecosystem के common abstractions के साथ integrate करता है।

यह:

  • logical service IDs के साथ काम कर सकता है,
  • Discovery Client से candidates प्राप्त कर सकता है,
  • RestClient, WebClient और related Spring HTTP integrations support करता है,
  • OpenFeign के साथ integrate हो सकता है,
  • Round-Robin और Random strategies provide करता है,
  • caching support देता है,
  • per-service custom configuration allow करता है।

इसलिए यह केवल Ribbon का renamed version नहीं है।

यह Spring Cloud ecosystem का अपना modern load-balancing abstraction और implementation है।


46. Common Mistakes#

1. Physical URL hardcode करना#

गलत architectural direction:

http://localhost:8081

जब multiple discovered instances use करनी हैं।

Logical service name use करें:

http://inventory-service


2. LoadBalancer dependency भूल जाना#

Discovery configured होने के बावजूद HTTP client load balancing infrastructure missing हो सकती है।

Required starter verify करें:

spring-cloud-starter-loadbalancer


3. @LoadBalanced annotation भूल जाना#

Normal builder और load-balanced builder behavior अलग हो सकता है।

Internal service call के लिए intended bean पर @LoadBalanced correctly configure करें।


4. Registry में केवल एक instance होना#

एक candidate होने पर distribution दिखाई नहीं देगी।

पहले registry check करें।


5. Random को Round-Robin जैसा expect करना#

Random strategy strict alternating sequence नहीं देती।


6. Service name typo#

inventory-service और inventoryservice एक ही ID नहीं हैं।


7. OpenFeign में fixed url देना#

Declarative interface होने के बावजूद physical URL hardcode करने पर discovery-based destination selection bypass हो सकती है।


8. Double caching ignore करना#

Discovery client और LoadBalancer दोनों caching कर रहे हों तो freshness characteristics समझें।


47. Hands-On Practice#

Practice 1#

Requirement

order-service को inventory-service call करना है। inventory-service की दो instances Service Registry में registered हैं। Caller को physical ports hardcode नहीं करने हैं।

Your Task

RestClient.Builder को Spring Cloud LoadBalancer के साथ configure करें और /inventory/instance endpoint logical service name से call करें।

HintShow Hint

@LoadBalanced और http://inventory-service पर ध्यान दें।

SolutionShow Solution
JAVA
@Configuration
public class ClientConfiguration {

    @Bean
    @LoadBalanced
    RestClient.Builder inventoryRestClientBuilder() {
        return RestClient.builder();
    }
}
JAVA
@Service
public class InventoryClient {

    private final RestClient restClient;

    public InventoryClient(
            @LoadBalanced RestClient.Builder builder) {

        this.restClient = builder
                .baseUrl("http://inventory-service")
                .build();
    }

    public String getInstance() {
        return restClient
                .get()
                .uri("/inventory/instance")
                .retrieve()
                .body(String.class);
    }
}

Explanation

यह solution physical port नहीं जानता।

inventory-service logical service ID है।

Load-balanced RestClient.Builder request को Spring Cloud LoadBalancer infrastructure से गुजरने देता है, जहाँ discovered candidates में से एक instance choose की जा सकती है।


Practice 2#

Requirement

inventory-service currently default Round-Robin selection use कर रही है। केवल इस service के लिए Random strategy configure करनी है।

Your Task

Custom RandomLoadBalancer bean बनाइए और उसे inventory-service के साथ associate कीजिए।

HintShow Hint

RandomLoadBalancer, LoadBalancerClientFactory, ServiceInstanceListSupplier और @LoadBalancerClient की आवश्यकता होगी।

SolutionShow Solution
JAVA
public class RandomInventoryLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment,
            LoadBalancerClientFactory factory) {

        String serviceId = environment.getProperty(
                LoadBalancerClientFactory.PROPERTY_NAME);

        return new RandomLoadBalancer(
                factory.getLazyProvider(
                        serviceId,
                        ServiceInstanceListSupplier.class),
                serviceId);
    }
}
JAVA
@Configuration
@LoadBalancerClient(
        name = "inventory-service",
        configuration = RandomInventoryLoadBalancerConfiguration.class)
public class InventoryLoadBalancerConfiguration {
}

Explanation

Discovery अभी भी candidate instances provide करेगी।

Difference केवल selection step में है।

अब default Round-Robin की बजाय configured Random strategy instance select करेगी।


Service Discovery और Load Balancer में सबसे important difference क्या है?Show Answer

Service Discovery available service instances खोजने और उनकी location information provide करने में मदद करती है।

Load Balancer उन्हीं available candidates में से एक instance select करके request distribution करता है।

सरल line में:

Discovery finds. LoadBalancer chooses.


Logical service URL में inventory-service क्या represent करता है?Show Answer

inventory-service physical host और port नहीं है।

यह service की logical identity या service ID है।

Load-balanced client इस ID को use करके discovered service instances में से actual physical destination resolve कर सकता है।


48. Interview Preparation#

What is client-side load balancing in microservices?Show Answer

Client-side load balancing is an approach in which the calling service obtains the available instances of a target service and selects one instance locally before sending the request. In Spring Cloud, Spring Cloud LoadBalancer can work with service discovery and logical service IDs to perform this selection.

Key Points:

  • Selection happens on the client side.
  • Service discovery provides candidate instances.
  • The caller uses a logical service ID.
  • A load-balancing algorithm selects a destination instance.

Why interviewer asks this:

The interviewer wants to verify that you understand service-to-service communication beyond simply calling a hardcoded URL.


What is the role of ServiceInstanceListSupplier in Spring Cloud LoadBalancer?Show Answer

ServiceInstanceListSupplier supplies the candidate ServiceInstance objects that the LoadBalancer can consider for a particular service. A discovery-backed supplier can retrieve instances through a Discovery Client, and additional supplier layers can provide behavior such as caching or filtering.

Key Points:

  • It supplies candidate instances.
  • It does not itself represent the selection algorithm.
  • It can be backed by service discovery.
  • Supplier chains can add behaviors such as caching.

Why interviewer asks this:

The interviewer is checking whether you understand the internal separation between instance discovery and instance selection.


What is the default load-balancing strategy in Spring Cloud LoadBalancer?Show Answer

The default implementation is RoundRobinLoadBalancer. Spring Cloud also provides RandomLoadBalancer, which can be configured when random instance selection is preferred.

Key Points:

  • Default is Round-Robin.
  • Random is an available alternative.
  • Strategies operate on available service instances.
  • Custom configuration can be applied per service.

Why interviewer asks this:

This checks practical knowledge of Spring Cloud LoadBalancer rather than only the general load-balancing concept.


How are Service Discovery and Spring Cloud LoadBalancer related?Show Answer

Service Discovery provides information about the available instances of a logical service. Spring Cloud LoadBalancer consumes candidate instances, applies a selection strategy, and routes the client request to the selected physical instance.

Key Points:

  • Discovery and load balancing are separate responsibilities.
  • Discovery provides locations.
  • LoadBalancer selects a destination.
  • Logical service names decouple callers from physical addresses.

Why interviewer asks this:

The interviewer wants to ensure that you do not confuse service registration, service discovery, and traffic distribution.


What replaced Netflix Ribbon in modern Spring Cloud applications?Show Answer

Spring Cloud LoadBalancer is the modern Spring Cloud replacement for Netflix Ribbon's client-side load-balancing role. Ribbon entered maintenance mode and should not be selected for new Spring Cloud applications.

Key Points:

  • Ribbon is legacy.
  • Spring Cloud LoadBalancer is the modern replacement.
  • Existing legacy systems may still mention Ribbon.
  • New development should follow current Spring Cloud LoadBalancer APIs.

Why interviewer asks this:

Legacy-to-modern migration knowledge is common in Spring microservices interviews.


49. Chapter Recap#

इस chapter से ये points strongly याद रखें:

  • Client-side load balancing में caller side instance selection होती है।
  • Service Discovery और Load Balancer अलग responsibilities हैं।
  • Discovery available instances देती है।
  • LoadBalancer candidate instances में से destination चुनता है।
  • spring-cloud-starter-loadbalancer Spring Cloud LoadBalancer integration provide करता है।
  • @LoadBalanced HTTP client builders को logical service IDs के साथ काम करने में सक्षम बनाता है।
  • RestClient और WebClient दोनों load-balanced service calls के लिए use किए जा सकते हैं।
  • ServiceInstanceListSupplier candidate instances provide करता है।
  • default strategy RoundRobinLoadBalancer है।
  • RandomLoadBalancer alternate selection strategy है।
  • Spring HTTP Service Clients current Spring Cloud versions में LoadBalancer integration use कर सकते हैं।
  • OpenFeign Spring Cloud LoadBalancer के साथ काम कर सकता है, लेकिन newer Spring direction HTTP Service Clients की ओर है।
  • Caching discovery lookups reduce कर सकती है, लेकिन stale data और double caching समझना जरूरी है।
  • Netflix Ribbon legacy technology है; modern replacement Spring Cloud LoadBalancer है।
  • सबसे important architectural habit है physical URLs hardcode करने की बजाय logical service identity use करना।
Summary

Microservices में caller को यह जानने की आवश्यकता नहीं होनी चाहिए कि target service अभी किस exact machine या port पर चल रही है। Caller logical service name use करती है, discovery candidates देती है, और Spring Cloud LoadBalancer appropriate instance select करके request वहाँ भेजता है।

Interactive learning

Practice lab

Apply this chapter with guided activities, immediate feedback, explanations, and retry.

Practice loads when this section enters view.