⌂ Index
Kapitel 16 · Cloud

Spring Cloud OpenFeign und Circuit Breaker

Typ: LibraryVersion 2 ausführlich

OpenFeign und Spring Cloud Circuit Breaker vereinfachen deklarative HTTP-Clients, Timeouts, Fallbacks und Resilience-Mechanismen.

Fachliche Einordnung

Remote Calls sind Fehlerquellen. Ohne Timeouts, Retry-Limits und Bulkheads können kleine Ausfälle ganze Plattformen blockieren.

Enterprise-Merksatz: OpenFeign und Spring Cloud Circuit Breaker vereinfachen deklarative HTTP-Clients, Timeouts, Fallbacks und Resilience-Mechanismen.

Technische Darstellung

Use Case Client Port Feign Adapter Circuit Breaker Remote Service Fallback
Kernkonzepte
  • Deklarativer HTTP-Client über Interface.
  • Timeouts und Fehlerdekodierung.
  • Circuit Breaker als Schutz vor Kaskadenfehlern.
  • Fallback nur für fachlich sichere Ersatzantworten.
  • Idempotenz als Voraussetzung für Retry.
Wann einsetzen?
  • Du konsumierst interne REST APIs synchron.
  • Du willst Service-Client-Code standardisieren.
  • Du brauchst kontrollierte Fehlerreaktion bei Downstream-Ausfällen.
Typische Fehler und Risiken
  • Fallback gibt erfundene Geschäftsdaten zurück.
  • Retries auf nicht-idempotenten POST-Operationen.
  • Kein Monitoring für offene Circuit Breaker.
Legacy- und Modernisierungssicht

SOAP- oder proprietäre Client-Stubs können hinter modernen Port-Interfaces liegen; Feign ist dann nur ein Adapter, nicht die Domäne.

Ausführliches Beispiel

Das Beispiel zeigt bewusst nicht nur Annotationen, sondern auch die Verantwortung der Schicht. In echten Projekten sollte der technische Spring-Code an Adapter- oder Konfigurationsrändern bleiben, während die Fachlogik testbar und möglichst frameworkarm bleibt.

@FeignClient(name = "pricing", url = "${clients.pricing.url}")
interface PricingClient {
    @GetMapping("/api/prices/{sku}")
    PriceResponse findPrice(@PathVariable String sku);
}

@Service
class PricingAdapter implements PricePort {
    private final PricingClient client;
    PricingAdapter(PricingClient client) { this.client = client; }

    @CircuitBreaker(name = "pricing", fallbackMethod = "fallbackPrice")
    public Money priceFor(String sku) {
        return client.findPrice(sku).toMoney();
    }

    Money fallbackPrice(String sku, Throwable ex) {
        throw new PriceUnavailableException(sku, ex); // sicherer als Fantasiepreis
    }
}
Checkliste für Reviews
  • Ist die Verantwortung des Bausteins klar: Framework steuert Lebenszyklus, Library wird gezielt benutzt?
  • Ist die Fachlogik außerhalb von Controller, Listener, Repository-Implementierung oder Konfiguration?
  • Sind Fehlerfälle, Timeouts, Security, Monitoring und Tests sichtbar modelliert?
  • Gibt es klare Grenzen zwischen DTO, Domäne, Persistence und Infrastruktur?