Microservices / Reliability

    Wzorce odporności systemów

    Circuit Breaker, Retry z Exponential Backoff, Bulkhead isolation, Backpressure — jak zapobiec cascade failure w mikrousługach.

    Circuit Breaker
    Izolacja awarii
    Retry + Jitter
    Przejściowe błędy
    Bulkhead
    Resource isolation
    Backpressure
    Consumer protection

    6 kluczowych wzorców odporności

    Każdy wzorzec rozwiązuje inny rodzaj awarii — od cascade failure przez wyczerpanie zasobów po przeciążenie consumer.

    Wzorzec Problem Mechanizm Narzędzia Overhead
    Circuit Breaker Cascade failure Przerywanie żądań do awarii Resilience4j, Polly, Istio Niski
    Retry + Backoff Przejściowe awarie Ponowne próby z delay Resilience4j, Polly, tenacity Niski-Średni
    Timeout Slow dependencies Max czas oczekiwania Wbudowany w HTTP clients Minimalny
    Bulkhead Wyczerpanie zasobów Izolacja thread pool/semaphore Resilience4j, Hystrix, K8s Quotas Średni
    Fallback Całkowita niedostępność Alternatywna odpowiedź Resilience4j, custom code Zależy od fallback
    Backpressure Przeciążenie consumer Sygnalizacja do producer Reactor, RxJava, Kafka Niski (reactive)

    Często zadawane pytania

    Co to są wzorce odporności (Resilience Patterns) i dlaczego są kluczowe?

    Resilience Patterns: wzorce projektowe zapewniające odporność systemów na awarie. W mikrousługach — cascade failure: jeden serwis pada, wywołuje chain reakcję i cały system pada. Cel wzorców odporności: izolacja awarii (failure isolation). Degradacja graceful (partial functionality zamiast full outage). Szybkie przywracanie. Kluczowe wzorce: Circuit Breaker: przerywa łańcuch wywołań do niedostępnego serwisu. Retry: ponów żądanie przy przejściowej awarii. Timeout: nie czekaj w nieskończoność. Bulkhead: izoluj zasoby per zależność. Fallback: alternatywna odpowiedź przy awarii. Rate Limiting/Throttling: chroń serwis przed przeciążeniem. Hedging: wyślij równoległe żądania, użyj pierwszej odpowiedzi. Backpressure: sygnalizuj upstream że nie możesz przetworzyć więcej. Gdzie stosować: między każdą parą serwisów w komunikacji synchronicznej. HTTP klient -> HTTP serwis. Message consumer -> external service call. Batch job -> external dependency. Narzędzia: Resilience4j (Java), Polly (.NET), go-resiliency (Go), Hystrix (Java, Netflix, deprecated), pybreaker (Python), tenacity (Python retry).

    Circuit Breaker Pattern — jak działa i jak skonfigurować?

    Circuit Breaker: naśladuje fizyczny bezpiecznik elektryczny. Stany: CLOSED (normalny) — żądania przechodzą. Liczy błędy. OPEN (awaria) — żądania blokowane natychmiastowo (nie czekają). Periodycznie próbuje half-open. HALF-OPEN (próba) — przepuszcza ograniczoną liczbę żądań. Jeśli sukces -> CLOSED. Jeśli błąd -> OPEN. Przejście CLOSED -> OPEN: sliding window (count lub time based). Count-based: 100 żądań, 50% failure rate. Time-based: ostatnie 10 sekund, 50% failure rate. Wait duration in open state: 30-60s standardowo. Slow calls: żądania które trwają za długo (np. > 2s) również liczone jako failures. Resilience4j konfiguracja: slidingWindowType COUNT_BASED. slidingWindowSize 10. failureRateThreshold 50. slowCallDurationThreshold 2000ms. slowCallRateThreshold 100. waitDurationInOpenState 30s. permittedNumberOfCallsInHalfOpenState 3. Fallback przy OPEN: return cached data. return default/empty response. redirect to backup service. throw degraded exception (graceful degradation). Metrics: resilience4j.circuitbreaker.{name}.state. transition events. call.failure.rate. Integracja: Spring Boot Actuator automatycznie eksponuje metryki. Prometheus + Grafana dashboard.

    Retry Pattern — kiedy ponawiać i kiedy nie?

    Retry: ponów żądanie przy przejściowej awarii. Nie wszystkie błędy są przejściowe. Retryable errors: 500 Internal Server Error (może być przejściowy). 503 Service Unavailable. Network timeout (connection reset). 429 Too Many Requests (z Retry-After). Non-retryable errors: 400 Bad Request (błąd klienta, retry nie pomoże). 401 Unauthorized (brak autentykacji, retry nie pomoże). 404 Not Found (zasób nie istnieje). 422 Unprocessable Entity. Retry strategies: Fixed Delay: czekaj 1s między próbami. Prosto ale retry storm. Exponential Backoff: 1s, 2s, 4s, 8s, 16s. Redukuje load na serwis. Exponential + Jitter: dodaj losowość. Bez jitter: wszystkie klienty czekają synchronicznie. Full Jitter: sleep = random(0, 2^attempt). Decorrelated Jitter (AWS): sleep = random(base, prev_sleep * 3). Max Retry attempts: 3-5 standardowo. Z Circuit Breaker: Circuit Breaker liczy failed retries. Retry budgets: globalny limit retry per czas (Google SRE). Idempotency wymagana: jeśli retry może powodować duplikaty -> endpoint musi być idempotentny. Resilience4j Retry: maxAttempts 3. waitDuration 500ms. exponentialBackoff multiplier 2. randomizedWaitFactor 0.5. retryExceptions [IOException, TimeoutException]. ignoreExceptions [BusinessException].

    Bulkhead Pattern — izolacja zasobów?

    Bulkhead: grodziowy system statku — każda komora izolowana. Awaria jednej komory nie topi całego statku. W systemach IT: izoluj thread pool / connection pool / semaphore per zależność. Bez Bulkhead: jeden slow external service zajmuje wszystkie wątki thread pool. Cały serwis niedostępny dla innych requestów. Z Bulkhead: każda zależność ma własny thread pool lub semaphore. Awaria jednej zależności nie wpływa na inne. Thread Pool Isolation: każda zewnętrzna zależność ma osobny thread pool. Hystrx thread pool isolation. Wada: overhead thread switching. Semaphore Isolation: limita liczby równoległych żądań do zależności. Lżejszy niż thread pool. Bez timeout per execution. Connection Pool Isolation: baza danych A — pool 10 połączeń. Baza danych B — pool 5 połączeń. Crash BD A nie wyczerpuje połączeń BD B. Resilience4j Bulkhead: maxConcurrentCalls 10 per dependency. maxWaitDuration 0ms (natychmiastowy błąd gdy pełny). Thread Pool Bulkhead: coreThreadPoolSize 2. maxThreadPoolSize 4. queueCapacity 2. keepAliveDuration 20ms. Kubernetes: Resource Quotas per namespace. Limit CPU/RAM per pod. PodDisruptionBudget. Service Mesh (Istio): connection pool per upstream service. maxConnections, pendingRequests, requests, retries.

    Backpressure — jak sygnalizować przeciążenie w systemach reaktywnych?

    Backpressure: mechanizm gdzie consumer informuje producer że nie może przetworzyć więcej danych. Przeciwieństwo push model (producer decyduje kiedy wysyłać). Pull model: consumer pobiera dane kiedy gotowy. Problem bez backpressure: producer produkuje szybciej niż consumer przetwarza. Bufory rosną -> OutOfMemoryError. Crash aplikacji. Backpressure strategie: DROP: odrzuć nowe dane gdy bufor pełny. ERROR: wyślij błąd do producera. LATEST: zachowaj tylko najnowsze dane. BUFFER: buforuj z limitem. BLOCK: blokuj producera. Reactive Streams (standard): Publisher -> Subscriber. request(N) — subscriber mówi ile może przetworzyć. onNext(), onError(), onComplete(). Project Reactor (Spring WebFlux): Flux/Mono z backpressure support. limitRate(), onBackpressureBuffer(), onBackpressureDrop(). RxJava: Flowable (backpressure-aware) vs Observable (bez). Backpressure operators: onBackpressureBuffer, onBackpressureDrop, onBackpressureLatest. Kafka Consumer: max.poll.records — ile rekordów per poll. pause()/resume() — dynamiczne wstrzymanie. Wstaw throttle gdy downstream wolny. gRPC streaming: flow control wbudowane (HTTP/2 flow control). Monitoring: queue depth metrics. Alerting gdy queue rośnie. Auto-scaling gdy persistently full queue.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz