GoDasturchi
Circuit Breaker in Services

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.

example.go
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.

Hints (0/3)

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

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

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.

example.go
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.

Hints (0/3)

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