সফটওয়্যার বা মাইক্রোসার্ভিস আর্কিটেকচারে সার্কিট ব্রেকার (Circuit Breaker) একটি অত্যন্ত গুরুত্বপূর্ণ ডিজাইন প্যাটার্ন।
সার্কিট ব্রেকার কী?
ধরুন, আপনার বাড়ির ইলেকট্রিক লাইনে হঠাৎ ওভারলোড হলো—একসাথে ফ্রিজ, এসি এবং ওভেন চালানোর কারণে অতিরিক্ত চাপ পড়ল। এই অবস্থায় বিদ্যুৎ সংযোগ স্বয়ংক্রিয়ভাবে বন্ধ না হলে ওয়্যারিং গলে যেতে পারে বা বড়সড় অগ্নিকাণ্ড ঘটতে পারে।
ঠিক এই বিপদ থেকে বাঁচাতে কাজ করে সার্কিট ব্রেকার! বিদ্যুৎ প্রবাহ বিপৎসীমা পার হলেই এটি ট্রিপ করে সংযোগ বিচ্ছিন্ন করে দেয়।
সফটওয়্যার ইঞ্জিনিয়ারিংয়েও সফটওয়্যার সার্কিট ব্রেকার ঠিক একইভাবে কাজ করে। কোনো API, ডেটাবেস বা এক্সটার্নাল সার্ভিস যদি হঠাৎ ধীরগতির হয়ে যায় বা কাজ করা বন্ধ করে দেয়, তখন সার্কিট ব্রেকার স্বয়ংক্রিয়ভাবে সেই সার্ভিসে রিকোয়েস্ট পাঠানো বন্ধ করে দেয়। ফলে পুরো সিস্টেম ক্র্যাশ করার হাত থেকে বেঁচে যায়।
বাস্তব উদাহরণ এবং ক্যাসকেডিং ফেইলিউর (Cascading Failure)
ধরুন, আপনি একটি ই-কমার্স ওয়েবসাইটের মালিক। পেমেন্ট সম্পন্ন করার জন্য আপনার ওয়েবসাইটটি একটি থার্ড-পার্টি পেমেন্ট গেটওয়ের (API) ওপর নির্ভরশীল।
এখন কোনো কারণে পেমেন্ট সার্ভারটি ডাউন হয়ে গেল বা খুব স্লো রেসপন্স দিচ্ছে। সার্কিট ব্রেকার না থাকলে যা হবে:
গ্রাহকরা পেমেন্ট বাটনে ক্লিক করে লোডিং স্ক্রিনে অপেক্ষা করবে এবং বিরক্ত হবে।
আপনার সার্ভার পেমেন্ট গেটওয়ের উত্তরের জন্য অপেক্ষা করতে করতে তার সমস্ত থ্রেড বা মেমরি ব্লক করে ফেলবে।
একপর্যায়ে আপনার সার্ভার নতুন কোনো গ্রাহককে সাইটে ঢুকতেই দেবে না।
একটি সার্ভিসের ব্যর্থতার কারণে পুরো ই-কমার্স ওয়েবসাইটটি ডাউন হয়ে যাবে। একে সফটওয়্যারের ভাষায় বলা হয় Cascading Failure।
এই মহাবিপর্যয় ঠেকানোর রক্ষাকবচ হলো সার্কিট ব্রেকার।
সার্কিট ব্রেকার কীভাবে কাজ করে? (৩টি স্টেট)
একটি সার্কিট ব্রেকার মূলত তিনটি স্টেটে (State) কাজ করে:
১. Closed (স্বাভাবিক অবস্থা): সবকিছু ঠিকঠাক চলছে। অ্যাপ্লিকেশন থেকে পাঠানো সব রিকোয়েস্ট সরাসরি পেমেন্ট সার্ভারে যাচ্ছে এবং রেসপন্স ফিরে আসছে।
২. Open (ত্রুটি ধরা পড়েছে, সার্ভার ব্লক!): ধরে নিই, সার্কিট ব্রেকারে নিয়ম করা আছে "পরপর ৩ বার ফেইল করলে ব্লক"। পেমেন্ট সার্ভিস যদি ৩ বার এরর দেয় বা টাইম-আউট হয়, সার্কিট ব্রেকার সাথে সাথে Open হয়ে যাবে। এখন নতুন কোনো ইউজার পেমেন্ট করতে চাইলে সিস্টেম আর পেমেন্ট সার্ভারে রিকোয়েস্ট পাঠাবে না। বরং সাথে সাথে ইউজারকে একটি মেসেজ দেখিয়ে দেবে। একে বলা হয় Fail-Fast। এতে সার্ভারের ওপর আর কোনো চাপ পড়ে না।
৩. Half-Open (টেস্টিং বা পর্যবেক্ষণ): সার্কিট ব্রেকার চিরকাল Open থাকে না। নির্দিষ্ট সময় (যেমন: ১০ সেকেন্ড) পার হওয়ার পর এটি Half-Open স্টেটে যায়। এই অবস্থায় এটি সীমিত সংখ্যক (১-২টি) রিকোয়েস্ট পেমেন্ট সার্ভারে পাঠিয়ে চেক করে দেখে সার্ভিসটি ঠিক হয়েছে কি না।
যদি রেসপন্স ঠিকঠাক আসে, তবে সার্কিট আবার Closed (স্বাভাবিক) হয়ে যায়।
যদি আবারও ফেইল করে, তবে সার্কিট পুনরায় Open হয়ে যায় এবং আরও ১০ সেকেন্ডের জন্য ব্লক থাকে।
কোড ইমপ্লিমেন্টেশন (Python)
পাইথনে pybreaker লাইব্রেরি ব্যবহার করে সার্কিট ব্রেকারের একটি উদাহরণ নিচে দেওয়া হলো। এখানে ফলব্যাক (Fallback) মেকানিজমও যুক্ত করা হয়েছে।
import pybreaker
import requests
# Circuit breaker setup: open for 10 seconds after 3 failures
payment_breaker = pybreaker.CircuitBreaker(fail_max=3, reset_timeout=10)
@payment_breaker
def process_payment():
# Calling a dummy payment service
response = requests.get("http://payment-service.local/pay", timeout=2)
response.raise_for_status()
return "Payment Successful!"
# Fallback Function
def fallback_payment():
return "Payment gateway is currently down. Please select 'Cash on Delivery'."
for i in range(1, 6):
try:
print(f"Attempt {i}:", process_payment())
except pybreaker.CircuitBreakerError:
# Executes when circuit breaker is in OPEN state
print(f"Attempt {i}: Circuit Breaker is OPEN! Request blocked. -> {fallback_payment()}")
except requests.exceptions.RequestException as e:
# General network or server error
print(f"Attempt {i}: Payment service failed!")
কোড ইমপ্লিমেন্টেশন (Java)
জাভাতে সার্কিট ব্রেকার ইমপ্লিমেন্ট করার জন্য বর্তমানে সবচেয়ে জনপ্রিয় লাইব্রেরি হলো Resilience4j। নিচে এর একটি বেসিক উদাহরণ দেওয়া হলো:
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import java.time.Duration;
import java.util.function.Supplier;
public class PaymentServiceDemo {
public static void main(String[] args) {
// Configure Circuit Breaker
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // Open if 50% of requests fail
.waitDurationInOpenState(Duration.ofSeconds(10)) // Wait 10s before Half-Open
.slidingWindowSize(4) // Check last 4 requests
.build();
CircuitBreaker circuitBreaker = CircuitBreaker.of("paymentService", config);
// Simulate multiple payment requests
for (int i = 1; i <= 6; i++) {
int attempt = i;
Supplier<String> paymentSupplier = CircuitBreaker.decorateSupplier(
circuitBreaker, () -> processPayment(attempt)
);
try {
String result = paymentSupplier.get();
System.out.println("Attempt " + attempt + ": " + result);
} catch (CallNotPermittedException e) {
// Executes when circuit breaker is in OPEN state
System.out.println("Attempt " + attempt + ": Circuit Breaker is OPEN! -> " + fallbackPayment());
} catch (Exception e) {
// General exception for simulated failure
System.out.println("Attempt " + attempt + ": Payment service failed!");
}
}
}
private static String processPayment(int attempt) {
// Simulating failure for the first 3 attempts
if (attempt <= 3) {
throw new RuntimeException("Server Error Simulated");
}
return "Payment Successful!";
}
private static String fallbackPayment() {
return "Gateway down. Please use Cash on Delivery.";
}
}
সার্কিট ব্রেকার ব্যবহারের প্রধান সুবিধা
সিস্টেম স্টেবল রাখে: একটি সার্ভিসের সমস্যার কারণে পুরো সিস্টেম যেন ক্র্যাশ না করে তা নিশ্চিত করে।
ফাস্ট রেসপন্স (Fail-Fast): ইউজারকে দীর্ঘক্ষণ লোডিং স্ক্রিনে আটকে না রেখে সাথে সাথে এরর বা বিকল্প মেসেজ দেখিয়ে দেয়।
রিসোর্স সাশ্রয়: ফেইল হওয়া API-তে বারবার রিকোয়েস্ট না পাঠিয়ে সার্ভারের মেমরি এবং থ্রেড বাঁচায়।
অটো-রিকভারি (Self-Healing): থার্ড-পার্টি সার্ভিস ঠিক হয়ে গেলে এটি ম্যানুয়াল হস্তক্ষেপ ছাড়াই স্বয়ংক্রিয়ভাবে পুনরায় কাজ শুরু করে।