CallMeTechie
EN Anmelden
Home Produkte Blog Über mich Kontakt

Monitoring & Resilienz

v1.x · Updated vor 1 Monat

Was macht es?

Uptime Monitoring prüft in regelmäßigen Abständen, ob die Backends deiner Routen erreichbar sind. Ohne Monitoring siehst du erst einen Fehler, wenn ein Benutzer ihn meldet.

Ohne Monitoring:

Client  →  Caddy  →  Backend (abgestürzt)  →  502 Bad Gateway
                                               ↑ niemand weiß es

Mit Monitoring:

Monitor prüft alle 60s  →  Backend antwortet nicht  →  Status: DOWN (rot)
                                                       → Email-Alert
                                                       → Webhook: route_monitor_down
                                                       → Circuit Breaker reagiert

Wie funktioniert es technisch?

GateControl startet einen Poller, der im konfigurierten Intervall (Standard: 60 Sekunden) alle Routen mit monitoring_enabled = 1 prüft.

HTTP-Routen (Layer 7):

  • HTTP GET auf http(s)://<Peer-IP>:<Target-Port>/
  • User-Agent: GateControl-Monitor/1.0
  • Erwartung: Statuscode 200-399 = UP, alles andere = DOWN
  • Bei backend_https: HTTPS mit rejectUnauthorized: false (akzeptiert Self-Signed)
  • Timeout: konfiguriert in config.timeouts.monitorHttp

L4-Routen (TCP/UDP):

  • TCP Connect zum Backend-Port
  • Verbindungsaufbau erfolgreich = UP, Timeout/Fehler = DOWN
  • Timeout: konfiguriert in config.timeouts.monitorTcp

Parallelisierung: Maximal 10 gleichzeitige Checks pro Zyklus.

Auto-WoL bei Gateway-Routen: Wenn eine Gateway-Route mit wol_enabled = 1 von UP auf DOWN wechselt, ruft der Monitor handleRouteDownDetected auf, das einen Magic Packet über das Gateway absetzt (gateways.notifyWol, Timeout 60s). So wacht der LAN-Host automatisch auf, wenn er ausgefallen ist — siehe concepts/home-gateway.md.

Gespeicherte Felder pro Route:

Feld Beschreibung
monitoring_status up, down oder unknown
monitoring_last_check Zeitpunkt der letzten Prüfung (ISO 8601)
monitoring_response_time Antwortzeit in Millisekunden
monitoring_last_change Zeitpunkt des letzten Statuswechsels

Use Cases

Synology NAS überwachen

Route nas.example.com → Port 5001 (DSM). Monitoring erkennt, wenn das NAS nach einem Update neu startet. Du bekommst eine E-Mail, wenn es down geht, und eine zweite, wenn es wieder erreichbar ist.

Mehrere Dienste auf einem Server

Drei Routen zeigen auf denselben Peer, aber verschiedene Ports (3000, 8080, 5432). Ein Dienst stürzt ab — Monitoring zeigt genau welcher. Die anderen bleiben grün.

Circuit Breaker aktivieren

Monitoring ist Voraussetzung für den Circuit Breaker. Erst wenn Monitoring einen Ausfall erkennt, kann der Circuit Breaker die Route sperren und 503 zurückgeben, statt Anfragen ins Leere zu schicken.

Kombination mit anderen Features

Kombination Wirkung
Monitoring + Circuit Breaker Monitoring-Checks treiben die State Machine des Circuit Breakers
Monitoring + Webhooks Events route_down / route_up an externe Systeme (Slack, Discord, etc.)
Monitoring + Email-Alerts Sofortige Benachrichtigung bei Statuswechsel
Monitoring + L4-Routen TCP-Check statt HTTP-Check, erkennt Port-Erreichbarkeit

Wichtige Hinweise

  • Der erste Check läuft 10 Sekunden nach dem Start von GateControl — damit alle Dienste Zeit haben hochzufahren.
  • Monitoring prüft die direkte Verbindung zum Backend (Peer-IP + Port), nicht den öffentlichen Domain-Zugang über Caddy.
  • Bei backend_https-Routen wird HTTPS verwendet, aber das Zertifikat nicht validiert — Self-Signed funktioniert.
  • Email-Alerts erfordern eine funktionierende SMTP-Konfiguration unter Settings → Email.
  • Webhook-Events heißen route_down und route_up (nicht route_monitor_down/route_monitor_up).
  • Das Monitoring-Intervall gilt global für alle Routen — individuelle Intervalle pro Route sind nicht möglich.
  • Wenn Monitoring deaktiviert wird, bleibt der letzte Status stehen (wird nicht auf unknown zurückgesetzt).

Was macht es?

Der Circuit Breaker erkennt, wenn ein Backend wiederholt nicht erreichbar ist, und schaltet die Route in einen Sperrmodus. Statt Anfragen ins Leere zu schicken (und Clients warten zu lassen), antwortet Caddy sofort mit 503.

Ohne Circuit Breaker:

Client 1  →  Caddy  →  Backend (tot)  →  30s Timeout  →  502
Client 2  →  Caddy  →  Backend (tot)  →  30s Timeout  →  502
Client 3  →  Caddy  →  Backend (tot)  →  30s Timeout  →  502
... 100 Clients warten gleichzeitig 30 Sekunden ...

Mit Circuit Breaker:

Monitoring: Backend tot (5x hintereinander)  →  Circuit Breaker: OPEN
Client 1  →  Caddy  →  503 "Service temporarily unavailable" (sofort, <1ms)
Client 2  →  Caddy  →  503 (sofort)
... nach 30s Timeout ...
Monitoring: Backend wieder da  →  Circuit Breaker: CLOSED
Client 3  →  Caddy  →  Backend  →  200 OK  ✓

Wie funktioniert es technisch?

Der Circuit Breaker implementiert eine State Machine mit drei Zuständen:

         Threshold Failures erreicht
 CLOSED ──────────────────────────────→ OPEN
   ↑                                      │
   │  Check erfolgreich                   │ Timeout abgelaufen
   │                                      ↓
   └──────────────────────────────── HALF-OPEN
           Check fehlgeschlagen ──→ OPEN

Zustände:

Status Caddy-Verhalten Badge-Farbe
Closed Normaler Betrieb, Anfragen werden weitergeleitet Grün
Open Caddy gibt sofort 503 mit Retry-After Header zurück Rot
Half-Open Monitoring-Check wird durchgelassen; bei Erfolg → Closed, bei Fehler → Open Amber

Konfigurierbare Werte:

Parameter Standard Beschreibung
Threshold 5 Aufeinanderfolgende Fehler bevor der Circuit öffnet
Timeout 30s Sekunden im Open-Status bevor ein Half-Open-Test stattfindet

Ablauf im Detail:

  1. Monitoring prüft das Backend periodisch
  2. Bei Fehler: Failure-Counter wird inkrementiert (cb_failure_count in der routes-Tabelle — persistiert über Neustarts hinweg)
  3. Bei Erfolg: Counter wird auf 0 zurückgesetzt
  4. Counter erreicht Threshold → Status wechselt zu open, cb_opened_at wird gesetzt
  5. Caddy-Config wird neu gebaut: Route liefert statische 503-Antwort
  6. Nach Timeout-Sekunden → Status wechselt zu half-open
  7. Nächster Monitoring-Check entscheidet:
    • Erfolg → closed, Caddy-Config wird wiederhergestellt
    • Fehler → open, Timer startet neu

Caddy-Konfiguration im Open-Status (aus src/services/caddyConfig.js):

{
  "handle": [{
    "handler": "static_response",
    "status_code": "503",
    "body": "Service temporarily unavailable",
    "headers": { "Retry-After": ["30"] }
  }]
}

Der Retry-After-Wert entspricht dem konfigurierten Timeout (Default 30).

Use Cases

Request-Stau bei totem Backend verhindern

Ohne Circuit Breaker warten alle eingehenden Anfragen auf den Caddy-Timeout (30s). Bei 100 gleichzeitigen Clients sind das 100 blockierte Verbindungen. Mit Circuit Breaker werden alle sofort mit 503 beantwortet.

Thundering Herd bei Recovery verhindern

Backend war 5 Minuten down, 1000 Clients haben gecacht und warten auf Retry. Ohne Circuit Breaker treffen alle 1000 Anfragen gleichzeitig auf das gerade gestartete Backend. Mit Half-Open lässt der Circuit Breaker nur einen Monitoring-Check durch — erst wenn der erfolgreich ist, wird die Route wieder geöffnet.

Schnelles Feedback für bessere UX

Statt 30 Sekunden auf einen Timeout zu warten, sieht der Benutzer sofort eine "Service vorübergehend nicht verfügbar" Seite. Die Seite kann einen Retry-After Header enthalten, den moderne Browser respektieren.

Kombination mit anderen Features

Kombination Wirkung
Circuit Breaker + Monitoring Pflicht: Monitoring-Checks treiben die State Machine
Circuit Breaker + Retry Retry versucht es bei geschlossenem Circuit; bei offenem Circuit sofort 503
Circuit Breaker + Load Balancing Circuit Breaker greift wenn alle Backends down sind
Circuit Breaker + Webhooks Events circuit_breaker_open / circuit_breaker_closed

Wichtige Hinweise

  • Monitoring ist Pflicht. Ohne aktiviertes Uptime Monitoring hat der Circuit Breaker keine Datenquelle und bleibt immer im Closed-Status.
  • Failure-Counter und Open-Timestamp werden in der Datenbank persistiert (cb_failure_count, cb_opened_at). Offene Circuits überleben Neustarts; fehlt der Timestamp nach einem Neustart, wird er beim ersten Check-Durchlauf neu gesetzt.
  • Der Circuit Breaker arbeitet pro Route, nicht pro Backend. Bei Load Balancing mit mehreren Backends öffnet der Circuit wenn das Monitoring-Ziel nicht erreichbar ist.
  • Im Open-Status werden keine Anfragen ans Backend weitergeleitet — Caddy antwortet mit 503 Service Unavailable + Retry-After-Header. Kein Bypass per API oder einzelnem Request.
  • Manueller Reset (seit v1.50.4): POST /api/v1/routes/:id/circuit-breaker/reset oder der Button Circuit-Breaker zurücksetzen im Route-Edit-Modal (nur sichtbar wenn Status ≠ closed). Setzt cb_failure_count = 0, cb_opened_at = NULL, Status auf closed, und re-rendert die Caddy-Config sofort. Ohne diesen Reset wartet ein offener Breaker auf den nächsten Monitoring-Zyklus und durchläuft den normalen open → half-open → closed-Pfad.
  • Circuit Breaker ist nur für HTTP-Routen verfügbar, nicht für L4 (TCP/UDP).

Was macht es?

Rate Limiting zählt die Anfragen jeder Client-IP und blockiert weitere Anfragen, sobald das Limit erreicht ist. Der Client erhält dann HTTP 429 (Too Many Requests) statt einer normalen Antwort.

Ohne Rate Limiting:

Bot sendet 10.000 Anfragen/Minute  →  Backend bearbeitet alle  →  Server überlastet

Mit Rate Limiting (100 Anfragen/Minute):

Bot sendet 100 Anfragen    →  Backend bearbeitet alle  ✓
Bot sendet Anfrage #101    →  Caddy: 429 Too Many Requests  ✕
Bot sendet Anfrage #102    →  Caddy: 429 Too Many Requests  ✕
... nach 1 Minute ...
Bot sendet Anfrage #1      →  Backend bearbeitet  ✓  (neues Zeitfenster)

Wie funktioniert es technisch?

GateControl nutzt das caddy-ratelimit Plugin für Route-Traffic. Der Rate-Limit-Handler wird vor dem Reverse Proxy in die Caddy Handler-Kette eingefügt (src/services/caddyConfig.js, rate_limit_enabled-Block).

Nicht zu verwechseln mit den Admin-API-Limitern (src/middleware/rateLimit.js): diese schützen das GateControl-Admin-UI (/login, /api/v1/*) und sind separat in Express konfiguriert. Das hier beschriebene Rate Limiting betrifft ausschließlich den Client-Traffic einer konfigurierten Route.

Caddy JSON-Konfiguration:

{
  "handler": "rate_limit",
  "rate_limits": {
    "static": {
      "key": "{http.request.remote.host}",
      "window": "1m",
      "max_events": 100
    }
  }
}

Schlüssel: {http.request.remote.host} — jede Client-IP bekommt ein eigenes Kontingent.

Konfigurierbare Werte:

Parameter Bereich Standard Beschreibung
Requests 1 – 100.000 100 Maximale Anfragen pro Zeitfenster
Window 1s, 1m, 5m, 1h 1m Dauer des Zeitfensters

Handler-Reihenfolge in Caddy:

  1. ACL / Forward Auth (falls aktiv)
  2. Custom Request Headers (falls vorhanden)
  3. Rate Limit ← hier
  4. Request Mirroring (falls aktiv)
  5. Compression (falls aktiv)
  6. Reverse Proxy

Use Cases

Login-Seite gegen Brute-Force schützen

Route app.example.com → Web-App mit Login. Rate Limit: 10 Requests / 1 Minute. Ein Angreifer kann maximal 10 Passwort-Versuche pro Minute machen — das verlangsamt Brute-Force-Angriffe erheblich.

API vor Missbrauch schützen

Route api.example.com → REST API. Rate Limit: 1000 Requests / 5 Minuten. Normale Nutzung bleibt unbeeinträchtigt, aber ein einzelner Client kann die API nicht überlasten.

Scraping verhindern

Route shop.example.com → Webshop. Rate Limit: 60 Requests / 1 Minute. Bots die Preise scrapen werden nach 60 Seitenaufrufen pro Minute gebremst.

Empfohlene Werte:

Use Case Requests Window
Login-Seite 10–20 1m
REST API 500–1000 5m
Webshop / Website 60–120 1m
Statische Assets 1000–5000 1m
Webhook-Endpoint 50–100 1m

Kombination mit anderen Features

Kombination Wirkung
Rate Limit + Route Auth Rate Limit nach Auth-Check — schützt Backend, nicht die Login-Seite
Rate Limit + Basic Auth Rate Limit vor Auth — schützt auch gegen Brute-Force auf Basic Auth
Rate Limit + ACL Nur VPN-Peers kommen durch, diese werden dann rate-limited
Rate Limit + IP-Filter IP-Filter blockiert bekannte IPs, Rate Limit bremst den Rest
Rate Limit + Compression Kein Konflikt — Rate Limit zählt Anfragen, Compression komprimiert Antworten

Wichtige Hinweise

  • Rate Limiting ist pro IP-Adresse, nicht global. 100 Requests/Minute bedeutet: jede einzelne IP darf 100 Anfragen stellen.
  • Hinter einem NAT-Router teilen sich alle Clients dieselbe IP — das Limit gilt dann für alle zusammen.
  • Erlaubte Window-Werte: 1s, 1m, 5m, 1h. Andere Werte werden auf 1m normalisiert.
  • HTTP 429 enthält keinen Retry-After Header — der Client muss selbst warten bis das Fenster abläuft.
  • Rate Limiting ist nur für HTTP-Routen verfügbar, nicht für L4 (TCP/UDP).
  • Bei Routen mit Forward Auth (Route Auth oder IP-Filter) wird Rate Limiting nach dem Auth-Check angewendet.
  • WebSocket-Verbindungen zählen nur den initialen HTTP Upgrade als eine Anfrage.

Was macht es?

Wenn das Backend einen Fehler zurückgibt oder nicht erreichbar ist, wiederholt Caddy die Anfrage automatisch, anstatt sofort einen Fehler an den Client zu senden.

Ohne Retry:

Client  →  Caddy  →  Backend (gerade neugestartet)  →  502 Bad Gateway  →  Client sieht Fehler

Mit Retry (3 Versuche):

Client  →  Caddy  →  Backend (Versuch 1: 502)
                  →  Backend (Versuch 2: 502)
                  →  Backend (Versuch 3: 200 OK)  →  Client sieht normale Antwort

Mit Retry + mehrere Backends:

Client  →  Caddy  →  Backend A (502)
                  →  Backend B (200 OK)  →  Client sieht normale Antwort

Wie funktioniert es technisch?

GateControl konfiguriert Caddys load_balancing.retries Mechanismus im Reverse-Proxy-Handler (src/services/caddyConfig.js, retry_enabled-Block):

Caddy JSON-Konfiguration:

{
  "handler": "reverse_proxy",
  "upstreams": [
    { "dial": "10.8.0.3:8080" }
  ],
  "load_balancing": {
    "retries": 3
  }
}

Verhalten:

  • Caddy wiederholt die Anfrage bis zu retries-mal bei Verbindungsfehlern
  • Mit einem Backend: alle Retries gehen an dasselbe Backend
  • Mit mehreren Backends: Retries rotieren zum nächsten Backend (Round Robin oder gewichtet)
  • Die Retry-Logik ist Teil von Caddys Load Balancer — kein separater Handler
  • Ausgelöst wird der Retry bei Connect-Fehlern und bei den Status-Codes aus dem UI-Feld Retry Status Codes. Diese Liste wird seit v1.50.4 tatsächlich an Caddy durchgereicht (reverse_proxy.load_balancing.retry_match), zusammen mit try_duration: 5s (ohne das ignoriert Caddy retries sonst). Ungültige Tokens (nicht-numerisch, außerhalb 100–599) werden stillschweigend verworfen.

Konfigurierbare Werte:

Parameter Bereich Standard Beschreibung
Retry Count 1 – 10 3 Anzahl der Wiederholungsversuche
Retry Status Codes CSV 502,503,504 Welche Response-Codes einen Retry triggern

Use Cases

Backend-Neustart abfangen

Route app.example.com → Node.js App auf Port 3000. Beim Deployment wird die App kurz neu gestartet (2-3 Sekunden Downtime). Mit 3 Retries und einem Backend überbrückt Caddy diese Lücke — der Client bemerkt bestenfalls eine leicht längere Ladezeit.

Load Balancing mit Failover

Route api.example.com → 3 API-Server (Backend A, B, C). Server B fällt aus. Caddy versucht B, bekommt einen Fehler, und leitet die Anfrage automatisch an C weiter. Der Client merkt nichts.

Temporäre 503-Fehler bei hoher Last

Route service.example.com → Microservice der bei Überlastung 503 zurückgibt. Mit Retries hat der Service einen Moment Zeit sich zu erholen, und die nächste Anfrage geht durch.

Kombination mit anderen Features

Kombination Wirkung
Retry + Load Balancing Retries rotieren zwischen Backends — effektiver als bei einem Backend
Retry + Circuit Breaker Circuit Breaker verhindert Retries wenn das Backend dauerhaft down ist
Retry + Monitoring Monitoring erkennt ob das Backend dauerhaft down ist; Retry hilft bei kurzen Aussetzern
Retry + Rate Limiting Jeder Retry-Versuch zählt als eine Anfrage für das Backend, nicht für das Rate Limit des Clients

Wichtige Hinweise

  • POST/PUT/DELETE werden ebenfalls wiederholt. GateControl führt keine automatische Idempotenz-Prüfung durch — der Admin muss selbst wissen, ob das Backend wiederholbare Schreiboperationen unterstützt. Beispiel: Ein Retry auf POST /api/orders könnte eine doppelte Bestellung auslösen. Retry nur aktivieren wenn das Backend idempotente Operationen unterstützt oder nur GET-Anfragen verarbeitet.
  • Retry ist nur für HTTP-Routen verfügbar, nicht für L4 (TCP/UDP).
  • Die Retries erfolgen sofort hintereinander — es gibt kein exponentielles Backoff.
  • Bei einem einzelnen Backend können Retries den Server zusätzlich belasten, wenn er bereits überlastet ist.
  • Retry Count von 1 bedeutet: 1 initialer Versuch + 1 Retry = maximal 2 Anfragen ans Backend.
  • Retries sind für den Client unsichtbar — er bekommt entweder die erfolgreiche Antwort oder den letzten Fehler.
  • In Kombination mit Circuit Breaker: Wenn der Circuit Breaker offen ist, werden keine Retries versucht (Caddy liefert sofort 503).

Cookie Settings

Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Essentielle Cookies sind immer aktiv.

Datenschutzerklärung
ESC
↑↓ navigate open esc close