Circuit Breaker in Services
Servislarda Circuit Breaker
"Go Design Patterns" kursida Circuit Breaker'ning asosini ko'rgan edingiz — endi uni mikroservislar kontekstida qo'llaymiz. Agar PaymentService butunlay ishlamay qolsa, OrderService har bir buyurtma uchun baribir unga so'rov yuborishda davom etsa ("Retry with Exponential Backoff" bilan qayta-qayta urinib ham) — bu ikkalasini ham sekinlashtiradi va foydalanuvchini kuttirib qo'yadi.
package main
import (
"errors"
"fmt"
)
type CircuitBreaker struct {
failureCount int
threshold int
open bool
}
func NewCircuitBreaker(threshold int) *CircuitBreaker {
return &CircuitBreaker{threshold: threshold}
}
func (cb *CircuitBreaker) Call(serviceName string, fn func() error) error {
if cb.open {
return fmt.Errorf("%s: circuit ochiq, so'rov rad etildi", serviceName)
}
err := fn()
if err != nil {
cb.failureCount++
if cb.failureCount >= cb.threshold {
cb.open = true
}
return err
}
cb.failureCount = 0
return nil
}
func callPaymentService() error {
return errors.New("payment-service javob bermayapti")
}
func main() {
cb := NewCircuitBreaker(2)
for i := 0; i < 3; i++ {
err := cb.Call("payment-service", callPaymentService)
fmt.Println(err)
}
}Uchinchi chaqiruvda PaymentServicening o'zi UMUMAN chaqirilmaydi (callPaymentService funksiyasi ishga tushmaydi) — buning o'rniga darhol "circuit ochiq" xatosi qaytadi. Bu — mikroservislar dunyosida muhim naqsh: agar PaymentService vaqtincha ishlamay qolsa, OrderService buni tezda "sezib", unga bo'lgan yukni to'xtatadi — bu ikkalasiga ham (ayniqsa qiynalayotgan PaymentServicega) tiklanish uchun vaqt beradi.
Katta tizimlarda har bir tashqi servis chaqiruvi uchun ALOHIDA Circuit Breaker ishlatiladi — agar PaymentService "ochiq" (ishlamayapti) bo'lsa ham, InventoryServicega so'rovlar odatdagidek davom etaveradi. Bu — bitta servisning muammosi butun tizimga "yoyilib ketishi"ning (cascading failure, "zanjirli qulash") oldini oladigan asosiy himoya vositalaridan biri.
>_ Exercise
Ikki xil servis uchun mustaqil Circuit Breaker ishlatilishini ko'rsating.
- •paymentCB (threshold=2) va inventoryCB (threshold=2) ikkita alohida CircuitBreaker yarating
- •paymentCB orqali 3 marta muvaffaqiyatsiz chaqiruv qiling (uchinchisi "circuit ochiq" bo'lishi kerak)
- •inventoryCB orqali BITTA muvaffaqiyatli chaqiruv qiling va uning xatosi nil ekanini chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Har bir tashqi servis uchun alohida Circuit Breaker ishlatish — bitta servisning muammosi boshqa servislarga ta'sir qilishining (zanjirli qulash) oldini oladi.
NEXT UP
Distributed Tracing Basics
$ go run main.go
Kodingizni ishga tushiring