Circuit Breaker patterns
মাইক্রোসার্ভিস আর্কিটেকচারে, একটি সার্ভিস প্রায়ই অন্য সার্ভিসের উপর নির্ভরশীল থাকে। যদি কোনো সার্ভিস down থাকে বা খুব ধীরগতিতে সাড়া দেয়, তাহলে পুরো সিস্টেমই অকার্যকর হয়ে যেতে পারে। এই সমস্যার সমাধান হলো Circuit Breaker Pattern।
Circuit Breaker কী?
Circuit Breaker Pattern হলো এমন একটি ডিজাইন প্যাটার্ন যা একটি সার্ভিসকে অপ্রাপ্য বা ব্যর্থ সার্ভিসে বারবার অনুরোধ পাঠানো থেকে রক্ষা করে। এটি বাস্তব সার্কিট ব্রেকারের মতো কাজ করে:
যখন কোনো সার্ভিস বারবার ব্যর্থ হয়, তখন সার্কিট “খোলা (Open)” হয় এবং কিছু সময়ের জন্য অনুরোধ বন্ধ রাখে।
Circuit Breaker কেন দরকার?
- সার্ভিস ব্যর্থতার কারণে cascading failure প্রতিরোধ করে
- অপ্রয়োজনীয় retry কমিয়ে সিস্টেমকে স্থিতিশীল রাখে
- latency ও response time উন্নত করে
- সিস্টেমকে graceful degradation করতে সাহায্য করে
Circuit Breaker এর তিনটি অবস্থা
| State | ব্যাখ্যা |
|---|---|
| Closed | সব অনুরোধ পাস হয়; যদি ব্যর্থতার হার বেড়ে যায়, সার্কিট খুলে যায় |
| Open | সার্ভিসে অনুরোধ বন্ধ; কিছু সময় পরে test করার সুযোগ দেয় |
| Half-Open | কিছু অনুরোধ test হিসেবে পাঠানো হয়; সফল হলে আবার Closed হয়ে যায় |
Spring Boot এ Circuit Breaker ব্যবহার
Spring Boot 2.3+ থেকে সহজেই Circuit Breaker ইমপ্লিমেন্ট করা যায় Resilience4j লাইব্রেরি ব্যবহার করে।
Step 1: Dependency যোগ করো
pom.xml এ নিচের dependency যোগ করো 👇
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
Step 2: একটি উদাহরণ সার্ভিস
ধরা যাক আমাদের একটি সার্ভিস PaymentService,
যা অন্য একটি সার্ভিসে REST API কল পাঠায়।
@Service
public class PaymentService {
private final RestTemplate restTemplate;
public PaymentService(RestTemplateBuilder builder) {
this.restTemplate = builder.build();
}
@CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackPayment")
public String processPayment() {
return restTemplate.getForObject("http://external-service/payment", String.class);
}
public String fallbackPayment(Exception ex) {
return "Payment service is currently unavailable. Please try again later!";
}
}
কী ঘটছে এখানে?
| Annotation / Method | কাজ |
|---|---|
@CircuitBreaker |
নির্দিষ্ট মেথডের জন্য সার্কিট ব্রেকার সক্রিয় করে |
name |
সার্কিট ব্রেকারের জন্য একটি ইউনিক নাম দেয় |
fallbackMethod |
ব্যর্থ হলে যে বিকল্প মেথডটি চালানো হবে তা নির্ধারণ করে |
Step 3: Configuration
application.yml ফাইলে সার্কিট ব্রেকার কনফিগার করো:
resilience4j:
circuitbreaker:
instances:
paymentService:
registerHealthIndicator: true
slidingWindowSize: 5
minimumNumberOfCalls: 5
failureRateThreshold: 50
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
Step 4: Controller তৈরি করো
@RestController
@RequestMapping("/api/payments")
public class PaymentController {
private final PaymentService paymentService;
public PaymentController(PaymentService paymentService) {
this.paymentService = paymentService;
}
@GetMapping
public ResponseEntity<String> makePayment() {
return ResponseEntity.ok(paymentService.processPayment());
}
}
Circuit Breaker Lifecycle
[CLOSED] → সার্ভিস ব্যর্থ → [OPEN] → সময় শেষে → [HALF-OPEN] → টেস্ট সফল → [CLOSED]
↳ ব্যর্থ → [OPEN]
যখন সার্ভিস বারবার ব্যর্থ হয় (যেমন 5টির মধ্যে 3টি failure),
Circuit Breaker “Open” হয়ে যায় এবং পরবর্তী কিছু সময় (যেমন 10 সেকেন্ড) অনুরোধ ব্লক করে রাখে।
Step 5: Metrics and Monitoring
Resilience4j Actuator support দিয়ে সার্কিট ব্রেকার স্ট্যাটাস মনিটর করতে পারো।
pom.xml এ যোগ করো:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
তারপর /actuator/health endpoint এ সার্কিট ব্রেকারের অবস্থা দেখা যাবে।
Optional: TimeLimiter ও Retry যোগ করা
তুমি চাইলে Circuit Breaker এর পাশাপাশি TimeLimiter এবং Retry ব্যবহার করতে পারো:
resilience4j:
timelimiter:
instances:
paymentService:
timeoutDuration: 3s
retry:
instances:
paymentService:
maxAttempts: 3
waitDuration: 500ms
এটি ৩ বার পর্যন্ত retry করবে, প্রতিবার ০.৫ সেকেন্ড করে অপেক্ষা করবে।
Circuit Breaker বনাম Retry
| বিষয় | Circuit Breaker | Retry |
|---|---|---|
| কাজ | সার্ভিস ব্যর্থ হলে অনুরোধ বন্ধ করে | ব্যর্থ হলে পুনরায় চেষ্টা করে |
| উদ্দেশ্য | সিস্টেমকে অতিরিক্ত চাপ থেকে রক্ষা করা | ট্রান্সিয়েন্ট সমস্যা কাটিয়ে ওঠা |
| ব্যবহার | যখন সার্ভিস দীর্ঘ সময় ব্যর্থ | যখন ব্যর্থতা অস্থায়ী |
Practical Example
@Service
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
@CircuitBreaker(name = "orderService", fallbackMethod = "fallbackOrder")
public String placeOrder() {
String payment = paymentService.processPayment();
return "Order placed successfully with " + payment;
}
public String fallbackOrder(Exception ex) {
return "Order placed but payment pending due to service issue.";
}
}
Logging এবং Observability
Resilience4j metrics গুলো Prometheus বা Micrometer এর মাধ্যমে export করা যায়।
তুমি চাইলে Grafana dashboard বানিয়ে real-time Circuit Breaker মনিটর করতে পারো।
Best Practices
- ছোট সার্ভিসগুলোতে Circuit Breaker যোগ করো
- সব fallback method এ ইউজার-ফ্রেন্ডলি বার্তা দাও
- Metrics মনিটর করো — কখন সার্ভিস repeatedly fail করছে
- Retry + Circuit Breaker একসাথে ব্যবহার করো না unless প্রয়োজন