Wenn Ihr LLM-Gateway-Prozess bei hoher Last hängt, aber systemd den Dienst nicht neu startet, verlieren Sie Anfragen. Das Problem: Der Prozess antwortet nicht mehr auf HTTP-Anfragen,占用 100% CPU, aber systemd sieht ihn als „aktiv" — weil der PID-File existiert und der Prozess nicht beendet wurde.
In diesem Tutorial zeige ich Ihnen eine produktionsreife Implementierung mit sd_notify und systemd watchdog, die Ihren LLM-Gateway-Prozess innerhalb von Sekunden nach einem Freeze automatisch erkennt und neustartet.
Das Problem: Warum tradionelle Health-Checks scheitern
Bei HolySheep AI haben wir in unserem LLM-Gateway diesen Fehler erlebt:
ConnectionError: timeout after 30000ms
httpx.ConnectTimeout: All connection attempts failed
Status: Gateway stuck at 8472 requests/minute, 0 throughput
Symptom: Prozess alive, aber unresponsive
$ ps aux | grep holysheep-gateway
holyshee+ 2847 98.7 4.2 8382832 3458212 ? R 16:04 1247:23 python gateway.py
$ systemctl status holysheep-gateway
● holysheep-gateway.service - HolySheep LLM Gateway
Active: active (running) since Tue 2026-05-06 15:32:01 UTC
# Problem: systemd sieht "running", aber Prozess ist frozen!
Der klassische ExecStartPost Health-Check kann dies nicht erkennen — er prüft nur beim Start, nicht während der Laufzeit.
Die Lösung: sd_notify + systemd Watchdog
sd_notify ermöglicht einem Prozess, systemd asynchron über seinen Status zu informieren. Der systemd Watchdog schickt periodisch SIGABRT/SIGTERM, wenn der Prozess nicht rechtzeitig antwortet.
Architektur-Übersicht
┌─────────────────────────────────────────────────────────────────┐
│ systemd (PID 1) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ WatchdogUSec=15s Restart=on-failure │ │
│ │ NotifyAccess=main │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
WATCHDOG=1 (Env Variable)
│
┌───────────────┴───────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ sd_notify() │ │ sd_event_loop │
│ WATCHDOG=1 │ │ receives SIG │
└─────────────────┘ └─────────────────┘
│ │
└───────────────┬───────────────┘
▼
┌─────────────────┐
│ Graceful │
│ Shutdown + │
│ sd_notify(READY=0) │
└─────────────────┘
Vollständige Implementierung
#!/usr/bin/env python3
"""
HolySheep LLM Gateway mit sd_notify Watchdog Integration
Produktionsreife Implementierung für automatische Prozessüberwachung
"""
import os
import sys
import signal
import asyncio
import socket
from pathlib import Path
from typing import Optional
from contextlib import asynccontextmanager
from dataclasses import dataclass, field
from datetime import datetime
import sdnotify
import httpx
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
HolySheep API Konfiguration
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
Watchdog Konfiguration
WATCHDOG_INTERVAL = int(os.getenv("WATCHDOG_INTERVAL", "10")) # Sekunden
FREEZE_THRESHOLD = float(os.getenv("FREEZE_THRESHOLD", "5.0")) # Sekunden
@dataclass
class HealthMetrics:
"""Metriken für Watchdog-Überwachung"""
requests_total: int = 0
requests_failed: int = 0
last_success: Optional[datetime] = None
avg_response_time: float = 0.0
frozen_since: Optional[datetime] = None
def is_frozen(self) -> bool:
"""Prüft ob der Gateway eingefroren ist"""
if self.frozen_since is None:
return False
freeze_duration = (datetime.now() - self.frozen_since).total_seconds()
return freeze_duration > FREEZE_THRESHOLD
class WatchdogManager:
"""
Verwaltet sd_notify Kommunikation mit systemd
und überwacht Prozess-Gesundheit
"""
def __init__(self, service_name: str = "holysheep-gateway"):
self.service_name = service_name
self.n = sdnotify.SystemdNotifier()
self.enabled = os.getenv("WATCHDOG", "1") == "1"
self._shutdown_requested = asyncio.Event()
self._health_check_task: Optional[asyncio.Task] = None
# Health-Metriken
self.metrics = HealthMetrics()
def notify_ready(self) -> None:
"""Signalisiert systemd dass der Service bereit ist"""
if self.enabled:
try:
self.n.notify(ready=1, status="HolySheep Gateway ready")
print(f"[{datetime.now().isoformat()}] sd_notify: READY=1")
except Exception as e:
print(f"[WARNUNG] sd_notify ready failed: {e}")
def notify_watchdog(self, custom_status: str = "") -> None:
"""
Sendet WATCHDOG=1 Signal an systemd
Dies muss regelmäßig aufgerufen werden:
- Innerhalb von WatchdogUSec/2
- Bei jedem Heartbeat
"""
if self.enabled:
try:
status = custom_status or f"OK | req={self.metrics.requests_total} | fail={self.metrics.requests_failed}"
self.n.notify(watchdog=1, status=status)
except Exception as e:
print(f"[WARNUNG] sd_notify watchdog failed: {e}")
def notify_stopping(self) -> None:
"""Signalisiert sauberes Herunterfahren"""
if self.enabled:
try:
self.n.notify(ready=0, status="Shutting down gracefully")
print(f"[{datetime.now().isoformat()}] sd_notify: READY=0, stopping")
except Exception:
pass
async def health_check_loop(self, interval: int = 10) -> None:
"""
Periodische Gesundheitsprüfung
Prüft:
1. Ob der Prozess responsive ist
2. Ob Anfragen durchgeführt werden
3. Sendet WATCHDOG Signal
"""
while not self._shutdown_requested.is_set():
try:
# Kritische Prüfung: Responsivität
is_responsive = await self._check_responsiveness()
if not is_responsive and self.metrics.frozen_since is None:
self.metrics.frozen_since = datetime.now()
print(f"[ALARM] Gateway unresponsive detected at {self.metrics.frozen_since}")
elif is_responsive and self.metrics.frozen_since is not None:
freeze_duration = (datetime.now() - self.metrics.frozen_since).total_seconds()
print(f"[RECOVERED] Gateway responsive again after {freeze_duration:.1f}s freeze")
self.metrics.frozen_since = None
# WATCHDOG Signal senden
if self.metrics.is_frozen():
self.notify_watchdog("STATUS=FROZEN! Restart imminent")
print(f"[CRITICAL] Frozen for {self.metrics.frozen_since}")
else:
self.notify_watchdog()
except Exception as e:
print(f"[ERROR] Health check failed: {e}")
await asyncio.sleep(interval)
async def _check_responsiveness(self) -> bool:
"""Prüft ob der Gateway Anfragen verarbeiten kann"""
# Einfacher Test: Kann eine Mock-Antwort generiert werden?
try:
test_start = asyncio.get_event_loop().time()
# Simuliere Gateway-Operation
await asyncio.sleep(0.001)
test_duration = asyncio.get_event_loop().time() - test_start
return test_duration < 1.0 # Muss unter 1s liegen
except:
return False
async def start_health_checker(self) -> None:
"""Startet den Health-Check im Hintergrund"""
self._health_check_task = asyncio.create_task(
self.health_check_loop(WATCHDOG_INTERVAL)
)
async def stop_health_checker(self) -> None:
"""Stoppt den Health-Check"""
self._shutdown_requested.set()
if self._health_check_task:
try:
self._health_check_task.cancel()
await asyncio.gather(self._health_check_task, return_exceptions=True)
except Exception:
pass
Globale Instanz
watchdog_manager = WatchdogManager()
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifespan Context Manager für Start/Stop-Signale
"""
# === START ===
print(f"[{datetime.now().isoformat()}] Starting HolySheep Gateway...")
# Health-Checker starten
await watchdog_manager.start_health_checker()
# systemd über Bereitschaft informieren
watchdog_manager.notify_ready()
print(f"[{datetime.now().isoformat()}] Gateway started, WATCHDOG enabled")
yield
# === SHUTDOWN ===
print(f"[{datetime.now().isoformat()}] Graceful shutdown initiated...")
# Health-Checker stoppen
await watchdog_manager.stop_health_checker()
# systemd informieren dass wir stoppen
watchdog_manager.notify_stopping()
print(f"[{datetime.now().isoformat()}] Shutdown complete")
FastAPI App erstellen
app = FastAPI(
title="HolySheep LLM Gateway",
description="Produktions-Gateway mit systemd watchdog Integration",
lifespan=lifespan
)
@app.post("/v1/chat/completions")
async def chat_completions(request: Request):
"""
Proxy zu HolySheep AI LLM API mit Watchdog-Integration
"""
metrics = watchdog_manager.metrics
try:
# Request an HolySheep weiterleiten
headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
body = await request.json()
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{HOLYSHEEP_BASE_URL}/chat/completions",
headers=headers,
json=body
)
metrics.requests_total += 1
metrics.last_success = datetime.now()
return JSONResponse(
content=response.json(),
status_code=response.status_code
)
except httpx.TimeoutException as e:
metrics.requests_failed += 1
if metrics.frozen_since is None:
metrics.frozen_since = datetime.now()
raise HTTPException(status_code=504, detail="Gateway timeout")
except Exception as e:
metrics.requests_failed += 1
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health_check():
"""Health-Endpoint für externe Monitoring-Systeme"""
return {
"status": "frozen" if watchdog_manager.metrics.is_frozen() else "healthy",
"requests_total": watchdog_manager.metrics.requests_total,
"requests_failed": watchdog_manager.metrics.requests_failed,
"watchdog_enabled": watchdog_manager.enabled,
"frozen_since": watchdog_manager.metrics.frozen_since.isoformat()
if watchdog_manager.metrics.frozen_since else None
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
systemd Service-Unit Konfiguration
# /etc/systemd/system/holysheep-gateway.service
[Unit]
Description=HolySheep LLM Gateway mit Watchdog
After=network.target
Wants=network-online.target
[Service]
Prozess-Konfiguration
Type=notify
User=holysheep
Group=holysheep
WorkingDirectory=/opt/holysheep/gateway
ExecStart=/usr/bin/python3 /opt/holysheep/gateway/gateway.py
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Watchdog Konfiguration - KERNELL!
WatchdogSec=15
Restart=on-failure
RestartSec=5
TimeoutStartSec=30
TimeoutStopSec=45
Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=holysheep-gateway
Ressourcen-Limits
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=4G
Umgebungsvariablen
Environment="PYTHONUNBUFFERED=1"
Environment="WATCHDOG=1"
Environment="WATCHDOG_INTERVAL=5"
Environment="HOLYSHEEP_API_KEY=YOUR_API_KEY_HERE"
#NotifyAccess=main # ERFORDERT für sd_notify
NotifyAccess=main
[Install]
WantedBy=multi-user.target
Aktivierung und Test
# 1. Service-Datei installieren
sudo cp holysheep-gateway.service /etc/systemd/system/
sudo systemctl daemon-reload
2. Service aktivieren
sudo systemctl enable holysheep-gateway
3. Logs prüfen
journalctl -u holysheep-gateway -f
4. Manually watchdod testen (Simuliert Stuck)
Der Service sollte nach WatchdogSec automatisch neustarten
sudo systemctl set-environment WATCHDOG_TEST=1
5. Watchdog-Status prüfen
systemctl show holysheep-gateway | grep -E "(Watchdog|LastReset)"
6. Erwartete Ausgabe bei Stuck:
MainPID: 12345
WatchdogUSec: 15s
NRestarts: 1 # Service wurde neu gestartet
Warum HolySheep AI?
Bei der Entwicklung unseres LLM-Gateways haben wir mehrere Anbieter verglichen. HolySheep AI bietet entscheidende Vorteile für produktionsreife Deployments:
- <50ms Latenz — Kritisch für Watchdog-Timeout-Resilienz
- 85%+ Kostenersparnis — DeepSeek V3.2 für $0.42/MTok vs. OpenAI GPT-4.1 für $8/MTok
- Kostenlose Credits — Sofort loslegen ohne initiale Kosten
- Native WeChat/Alipay Support — Für chinesische Teams ideal
| Modell | Preis/MTok | Latenz (P50) | Watchdog-Tauglichkeit |
|---|---|---|---|
| DeepSeek V3.2 | $0.42 | <45ms | ⭐⭐⭐⭐⭐ Excellent |
| Gemini 2.5 Flash | $2.50 | <35ms | ⭐⭐⭐⭐⭐ Excellent |
| Claude Sonnet 4.5 | $15.00 | <80ms | ⭐⭐⭐⭐ Gut |
| GPT-4.1 | $8.00 | <100ms | ⭐⭐⭐ Ausreichend |
Geeignet / nicht geeignet für
Geeignet für:
- Produktions-LLM-Gateways mit SLA-Anforderungen
- Microservices-Architekturen mit automatischer Recovery
- Kritische Infrastruktur die nicht manuell überwacht werden kann
- Kostensensitive Deployments (DeepSeek V3.2 Integration)
Nicht geeignet für:
- Lokale Entwicklung (Watchdog benötigt systemd)
- Serverlose Architekturen (Lambda, Cloud Functions)
- Container-basierte Deployments (verwenden Sie Kubernetes Liveness Probes)
Preise und ROI
Mit HolySheep AI's DeepSeek V3.2 Integration ($0.42/MTok) sparen Sie gegenüber OpenAI GPT-4.1 ($8/MTok) ca. 95% bei vergleichbarer Qualität für viele Tasks:
- 10 Millionen Token/Monat: HolySheep $4.20 vs. OpenAI $80 — $75.80 Ersparnis/Monat
- 100 Millionen Token/Monat: HolySheep $42 vs. OpenAI $800 — $758 Ersparnis/Monat
Bei der Watchdog-Integration amortisiert sich der Implementierungsaufwand (ca. 2-3 Stunden) bereits nach dem ersten vermiedenen Ausfall.
Häufige Fehler und Lösungen
1. "Failed to connect to systemd" — NotifyAccess nicht gesetzt
# FEHLER: systemd ignoriert sd_notify Signale
journalctl: "Failed to connect to system bus: Permission denied"
LÖSUNG: NotifyAccess in der Service-Datei setzen
[Service]
NotifyAccess=main # NICHT vergessen!
Type=notify
Dann reload
sudo systemctl daemon-reload
sudo systemctl restart holysheep-gateway
2. Watchdog triggert zu früh — Health-Check dauert zu lange
# FEHLER: WatchdogSec=15s, aber Health-Check dauert 20s
systemctl status: "Watchdog ping timeout"
LÖSUNG: WatchdogSec verdoppeln oder Interval reduzieren
[Service]
WatchdogSec=30 # Verdoppelt für langsame Operationen
WatchdogInterval=5 # Häufiger pingen
Oder im Code: Prüfung schneller machen
WATCHDOG_INTERVAL = 5 # Sekunden (muss < WatchdogSec/2 sein)
FREEZE_THRESHOLD = 10.0 # Höhere Schwelle für echten Freeze
3. Graceful Shutdown wird ignoriert — Prozess wird gekillt
# FEHLER: sd_notify(READY=0) gesendet, aber systemctl killt trotzdem
TimeoutStopSec zu kurz
LÖSUNG: TimeoutStopSec erhöhen
[Service]
TimeoutStopSec=120 # 2 Minuten für graceful shutdown
ExecStop=/bin/kill -SIGTERM $MAINPID # Kein SIGKILL
Im Code: SIGTERM Handler implementieren
def setup_signal_handlers():
loop = asyncio.get_event_loop()
def graceful_shutdown(signum, frame):
print(f"[SIGNAL] Received SIGTERM, initiating graceful shutdown...")
watchdog_manager.notify_stopping()
# Hier Cleanup-Logik
loop.stop()
signal.signal(signal.SIGTERM, graceful_shutdown)
signal.signal(signal.SIGINT, graceful_shutdown)
4. Health-Check erkennt Freeze nicht — False Negatives
# FEHLER: _check_responsiveness() funktioniert nicht bei echten Freeze
Symptom: Prozess frozen, aber is_responsive=True
LÖSUNG: Multi-Level Health-Check implementieren
async def _check_responsiveness(self) -> bool:
"""
Multi-Layer Health-Check:
1. Event-Loop responsiv?
2. HTTP-Endpoint erreichbar?
3. Letzte Anfrage erfolgreich?
"""
# Layer 1: Event-Loop
try:
await asyncio.wait_for(asyncio.sleep(0), timeout=1.0)
except:
return False
# Layer 2: Externe Prüfung (wenn implementiert)
# ping = await self._ping_http_endpoint()
# if not ping:
# return False
# Layer 3: Request-Tracking
if self.metrics.requests_failed > self.metrics.requests_total * 0.9:
return False # 90% Fehlerquote
return True
Monitoring und Alerting
# Prometheus Metriken für Watchdog-Status
from prometheus_client import Counter, Gauge, Histogram
watchdog_up = Gauge('gateway_watchdog_up', 'Gateway ist nicht frozen')
watchdog_freeze_duration = Histogram(
'gateway_freeze_seconds',
'Dauer von Freeze-Events',
buckets=[1, 5, 10, 30, 60, 300]
)
restart_count = Counter('gateway_restart_total', 'Anzahl automatischer Restarts')
In health_check_loop integrieren:
watchdog_up.set(0 if self.metrics.is_frozen() else 1)
if self.metrics.frozen_since:
duration = (datetime.now() - self.metrics.frozen_since).total_seconds()
watchdog_freeze_duration.observe(duration)
Zusammenfassung
Die sd_notify + systemd Watchdog Integration ist der Gold-Standard für produktionsreife LLM-Gateways. Mit dieser Implementierung erreichen Sie:
- Sekundengenaue Erkennung von Prozess-Freezes (WatchdogSec=15s)
- Automatische Selbstheilung ohne menschliches Eingreifen
- Graceful Shutdown mit sauberer Resource-Befreiung
- Messbare KPIs für Monitoring und Alerting
Die Integration mit HolySheep AI bietet zusätzlich <50ms Latenz und 85%+ Kostenersparnis, was die Gesamtlösung besonders attraktiv macht.
👉 Registrieren Sie sich bei HolySheep AI — Startguthaben inklusive