1. Learning Outcomes#
इस chapter के बाद आप:
- Client-Side Load Balancing का वास्तविक मतलब समझ पाएँगे।
- Service Discovery और Load Balancing के बीच का संबंध समझ पाएँगे।
spring-cloud-starter-loadbalancerdependency का purpose समझ पाएँगे।- logical service name जैसे
inventory-serviceसे multiple instances resolve करना समझ पाएँगे। ServiceInstanceListSupplierकी भूमिका समझ पाएँगे।- default Round-Robin और Random selection strategy में अंतर समझ पाएँगे।
@LoadBalancedके साथRestClient.BuilderऔरWebClient.Builderconfigure कर पाएँगे।- 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#
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-serviceon port8081inventory-serviceon port8082inventory-serviceon port8083
अब 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 कर सकता है।
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 चाहिए जो:
- available instances खोजे,
- उनमें से एक healthy candidate चुने,
- request उस instance को भेजे,
- अगली 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 ध्यान से देखें।
Rendering diagram…
Diagram could not be rendered.
इस diagram में सबसे important observation यह है कि application सीधे पहले से fixed 8081 या 8082 select नहीं कर रही।
Application logical service name use करती है।
Spring Cloud LoadBalancer discovery से मिली candidate list में से actual destination चुनता है।
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 किया जा सकता है:
<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:
implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'यह starter Spring Cloud LoadBalancer infrastructure उपलब्ध कराता है।
केवल 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-serverorder-serviceinventory-serviceinstance Ainventory-serviceinstance B
दोनों inventory instances का application name समान होगा:
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 रख सकते हैं।
@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 किया जा सकता है:
java -jar inventory-service.jar --server.port=8081 --app.instance-id=inventory-1दूसरी instance:
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 है।
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 बनाइए:
@Configuration
public class HttpClientConfiguration {
@Bean
@LoadBalanced
RestClient.Builder loadBalancedRestClientBuilder() {
return RestClient.builder();
}
}यहाँ @LoadBalanced सबसे important annotation है।
अब इस builder से बनाई गई client logical service name के साथ request कर सकती है।
@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 बना सकते हैं:
@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 करें:
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:
@Configuration
public class ReactiveHttpClientConfiguration {
@Bean
@LoadBalanced
WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}Client:
@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 क्या है?#
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:
Rendering diagram…
Diagram could not be rendered.
यहाँ learner को तीन layers अलग-अलग समझनी चाहिए:
- Service Registry service registrations रखती है।
- ServiceInstanceListSupplier candidate list उपलब्ध कराता है।
- LoadBalancer candidate list में से destination चुनता है।
इन तीनों responsibilities को mix करने से architecture समझना कठिन हो जाता है।
18. Custom ServiceInstanceListSupplier configuration#
Default behavior काफी applications के लिए पर्याप्त हो सकता है।
लेकिन Spring Cloud LoadBalancer supplier chain customize करने की सुविधा भी देता है।
उदाहरण:
public class InventoryInstanceSupplierConfiguration {
@Bean
ServiceInstanceListSupplier serviceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.build(context);
}
}फिर इसे specific service के लिए attach किया जा सकता है:
@Configuration
@LoadBalancerClient(
name = "inventory-service",
configuration = InventoryInstanceSupplierConfiguration.class)
public class InventoryLoadBalancerClientConfiguration {
}यह configuration बताती है कि inventory-service के लिए instance list discovery से आए और supplier chain caching भी use करे।
@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:
Rendering diagram…
Diagram could not be rendered.
यह 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 है।
पाँच requests में exact equal distribution न मिलने पर Random strategy को faulty मत मानिए। Random selection small sample में naturally uneven दिखाई दे सकती है।
23. RandomLoadBalancer configure करना#
Specific service के लिए custom LoadBalancer configuration बनाई जा सकती है।
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 करें:
@Configuration
@LoadBalancerClient(
name = "inventory-service",
configuration = RandomLoadBalancerConfiguration.class)
public class InventoryRandomLoadBalancerClientConfiguration {
}अब उस service के लिए RandomLoadBalancer use किया जा सकता है।
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:
Rendering diagram…
Diagram could not be rendered.
Conceptually physical URI runtime पर ऐसा बन सकता है:
http://host-b:8082/inventory/instance
Application code को उस physical address को manually construct करने की आवश्यकता नहीं पड़ती।
26. @LoadBalanced के साथ multiple builders#
कभी application को दो प्रकार के HTTP clients चाहिए:
- internal microservice calls के लिए load-balanced client
- external APIs के लिए normal client
ऐसी स्थिति में beans को clearly distinguish करना अच्छा है।
@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 किया जा सकता है।
हर 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:
@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 किया जा सकता है:
@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:
spring:
http:
serviceclient:
inventory:
base-url: lb://inventory-serviceयह स्पष्ट करता है कि destination load-balanced service ID है।
दूसरी ओर अगर आप physical URL set कर दें:
spring:
http:
serviceclient:
inventory:
base-url: http://localhost:8081तो आपने destination पहले से fixed कर दी।
ऐसे physical base URL के साथ discovery-based instance selection का उद्देश्य समाप्त हो जाता है।
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:
@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 होना चाहिए।
<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 की जा सकती है:
@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 है:
@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 करना चाहिए।
@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 भेजें#
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/instanceRound-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 की जाए।
Rendering diagram…
Diagram could not be rendered.
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 किए जा सकते हैं।
spring:
cloud:
loadbalancer:
cache:
enabled: true
ttl: 35s
capacity: 256ttl का अर्थ है cache entry कितनी देर बाद expire होगी।
capacity cache की initial capacity से संबंधित setting है।
Defaults framework version के साथ बदल सकते हैं। Production configuration को अपने Spring Cloud release और operational requirements के अनुसार verify करना चाहिए।
36. Cache हमेशा बेहतर नहीं होता#
Caching performance improve कर सकती है, लेकिन stale information का risk भी introduce करती है।
मान लें:
- cache में दो instances हैं,
- एक instance remove हो गई,
- 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 हो सकता है।
उदाहरण:
spring:
cloud:
loadbalancer:
cache:
enabled: falseयह blindly हर project में apply नहीं करना चाहिए।
पहले समझें कि आपका discovery implementation क्या cache कर रहा है।
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:
Rendering diagram…
Diagram could not be rendered.
इस 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 करता है।
Zero candidates in means zero candidates out. LoadBalancer केवल available information पर काम कर सकता है।
40. Failure case: Service name mismatch#
Provider:
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 बनाया:
@Bean
@LoadBalanced
RestClient.Builder loadBalancedBuilder() {
return RestClient.builder();
}लेकिन client class में directly यह कर दिया:
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 में याद रखें:
Rendering diagram…
Diagram could not be rendered.
इस 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 नहीं है।
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
@Configuration
public class ClientConfiguration {
@Bean
@LoadBalanced
RestClient.Builder inventoryRestClientBuilder() {
return RestClient.builder();
}
}@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
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);
}
}@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-loadbalancerSpring Cloud LoadBalancer integration provide करता है।@LoadBalancedHTTP client builders को logical service IDs के साथ काम करने में सक्षम बनाता है।RestClientऔरWebClientदोनों load-balanced service calls के लिए use किए जा सकते हैं।ServiceInstanceListSuppliercandidate instances provide करता है।- default strategy
RoundRobinLoadBalancerहै। RandomLoadBalanceralternate 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 करना।
Microservices में caller को यह जानने की आवश्यकता नहीं होनी चाहिए कि target service अभी किस exact machine या port पर चल रही है। Caller logical service name use करती है, discovery candidates देती है, और Spring Cloud LoadBalancer appropriate instance select करके request वहाँ भेजता है।