7 Anwendungsfälle von Load Balancer – detaillierte Erklärung mit Beispielen
1. Überblick
Wenn es um Load Balancer (LB) geht, denken viele nur simpel daran: „es verteilt Anfragen auf mehrere Server”. Tatsächlich macht LB viel mehr — von SSL-Entlastung über Session-Verwaltung bis hin zu DDoS-Schutz und Backend-Gesundheitsprüfung.
Dieser Artikel behandelt 7 Hauptanwendungsfälle von Load Balancer, jeder mit konkreten Konfigurations- oder Code-Beispielen (nginx, Spring Boot, Kubernetes), damit du dir klar machen kannst, wie es in echten Systemen funktioniert. Danach wirst du wissen, welche Funktionen du auf welchem LB aktivieren musst und wirst häufige Konfigurationsfehler vermeiden.
2. Lastverteilung (Traffic Distribution)
Dies ist die Grundfunktion: LB empfängt Anfragen vom Client und leitet sie nach einem bestimmten Algorithmus an einen von mehreren Backend-Servern weiter — Round Robin, Least Connections, Weighted Round Robin …
upstream order_service {
server 10.0.1.11:8080;
server 10.0.1.12:8080;
server 10.0.1.13:8080;
}
server {
listen 80;
location /orders/ {
proxy_pass http://order_service;
}
}
upstream deklariert 3 Instanzen des OrderService. nginx verwendet standardmäßig Round Robin — Anfrage 1 geht an .11, Anfrage 2 an .12, Anfrage 3 an .13, dann wieder an .11. Wenn eine Instanz schwerere Anfragen verarbeitet, kannst du zu least_conn; wechseln, damit nginx den Server mit den wenigsten offenen Verbindungen bevorzugt.
Hinweis: Round Robin beachtet nicht, wie belastet die Server sind. Wenn die Instanzen unterschiedliche Leistung haben (z.B. ein Server mit stärkerer Hardware), verwende
weight:server 10.0.1.11:8080 weight=3; server 10.0.1.12:8080 weight=1;
3. SSL Termination
Anstatt dass jeder Backend TLS selbst entschlüsselt (kostet CPU), delegierst du das an den LB. LB hält das Zertifikat, entschlüsselt HTTPS zu reinem HTTP und leitet es dann ins interne Netz weiter.
server {
listen 443 ssl;
server_name api.nonladev.com;
ssl_certificate /etc/nginx/certs/nonladev.crt;
ssl_certificate_key /etc/nginx/certs/nonladev.key;
location / {
proxy_pass http://order_service; # HTTP pur, keine TLS nötig
proxy_set_header X-Forwarded-Proto https;
}
}
Dadurch muss der OrderService in Spring Boot keine server.ssl.*-Konfiguration haben — er läuft einfach normales HTTP auf Port 8080. Der Header X-Forwarded-Proto hilft dem Backend zu wissen, dass die ursprüngliche Anfrage HTTPS war, damit es die Umleitungs-URLs richtig generiert.
Hinweis: Falls das interne Netz zwischen LB und Backend nicht vertrauenswürdig ist (z.B. über mehrere Subnetze oder verschiedene Cloud-Anbieter), verwende nicht nur Termination — nutze „SSL Bridging”: LB entschlüsselt und verschlüsselt mit einem internen Zertifikat erneut, bevor es weiterleitet.
4. Session-Persistenz
Wenn das Backend die Session im Memory speichert (lokale Session), müssen alle Anfragen desselben Benutzers immer an dieselbe Instanz gehen, sonst wird der Benutzer zufällig „abgemeldet”.
upstream order_service {
ip_hash; # gleiche Client-IP -> gleicher Server
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
ip_hash hasht die Client-IP, um konstant einen Server aus dem Upstream auszuwählen. Eine andere Möglichkeit ist Sticky Session basierend auf Cookies — der LB fügt selber ein Cookie hinzu, das die Instanz markiert; das funktioniert auch, wenn der Client hinter einem gemeinsamen NAT steht.
Eine robustere Lösung ist, auf Sticky Session zu verzichten und die Session nach außen zu verlagern mit Spring Session + Redis:
@Configuration
@EnableRedisHttpSession
public class SessionConfig {
}
spring.data.redis.host=redis.internal
spring.data.redis.port=6379
Mit dieser Konfiguration wird die Session in Redis statt im Memory jeder Instanz gespeichert. Anfragen können zu jedem Server gehen und die Session lesen — der LB kann normales Round Robin verwenden, braucht ip_hash nicht mehr.
Hinweis:
ip_hashkann zu einer unausgewogenen Lastverteilung führen, wenn mehrere Benutzer ein NAT teilen (z.B. im Büro) — ihr gesamter Traffic konzentriert sich auf einen Server. Priorisiere es, Sessions zu externalisieren, wenn das System bereits groß ist.
5. Hohe Verfügbarkeit (High Availability)
Der LB überwacht die Backend-Server ständig; wenn eine Instanz ausfällt, entfernt der LB sie automatisch aus der Liste und verteilt den Traffic auf die verbleibenden Instanzen — alles geschieht, ohne dass der Client es merkt.
upstream order_service {
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 max_fails=3 fail_timeout=30s;
}
max_fails=3 bedeutet: nach 3 aufeinanderfolgenden fehlgeschlagenen Anfragen markiert nginx den Server als „down” für 30 Sekunden (fail_timeout) und sendet keine neuen Anfragen mehr dorthin. Nach 30 Sekunden versucht nginx es erneut — wenn der Server wiederhergestellt wurde, wird er wieder in die Rotation aufgenommen.
[14:02:01] 10.0.1.12 Timeout -> Fehleranzahl 1
[14:02:05] 10.0.1.12 Timeout -> Fehleranzahl 2
[14:02:09] 10.0.1.12 Timeout -> Fehleranzahl 3 -> als DOWN markiert für 30s
[14:02:09] Traffic umgeleitet zu 10.0.1.11
[14:02:39] 10.0.1.12 erneut versucht -> healthy -> zurück im Pool
Durch diesen Mechanismus führt ein Instanz-Crash nicht zum Zusammenbruch des gesamten Systems — das ist die Grundlage der High Availability auf der Netzwerkschicht.
6. Horizontale Skalierbarkeit (Scalability)
Der LB ist eine Voraussetzung für Horizontal Scaling: du fügst eine neue Instanz hinzu, der LB erkennt sie automatisch und verteilt die Last — ohne dass du Backend-Code ändern musst.
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 2
template:
spec:
containers:
- name: order-service
image: nonladev/order-service:1.4.0
ports:
- containerPort: 8080
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Hier balanciert der Kubernetes Service (der als interner LB fungiert) den Traffic automatisch zwischen den order-service-Pods. Der HorizontalPodAutoscaler überwacht die CPU — wenn sie über 70% hinausgeht, erstellt Kubernetes zusätzliche Pods (maximal 10), und der LB fügt die neuen Pods sofort zur Serving-Liste hinzu, ohne neu zu deployen oder neuzustarten.
Hinweis: Scaling funktioniert nur effektiv, wenn das Backend zustandslos ist (oder die Session wie in Punkt 4 externalisiert wurde). Andernfalls erhalten neu hinzugefügte Pods keine alten Sessions des Benutzers.
7. DDoS-Abschwächung (DDoS Mitigation)
Der LB steht an der Schnittstelle und ist daher der ideale Ort, um anomalen Traffic zu blockieren, bevor er das Backend erreicht — durch Rate Limiting oder Verteilung des Traffic auf eine breitere Basis.
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
server {
location /orders/ {
limit_req zone=api_limit burst=10 nodelay;
proxy_pass http://order_service;
}
}
limit_req_zone begrenzt jede IP auf maximal 20 Anfragen pro Sekunde. burst=10 erlaubt kurzfristig bis zu 10 Anfragen in der Warteschlange, nodelay verarbeitet Bursts sofort anstatt sie zu drosseln. Wird dieses Limit überschritten, antwortet nginx mit 503 Service Temporarily Unavailable, anstatt die Anfragen auf das Backend zu häufen.
Falls du Rate Limiting auf der Application-Ebene brauchst (zusätzlich, nicht als Ersatz des LB), nutze Bucket4j in Spring Boot:
<dependency>
<groupId>com.bucket4j</groupId>
<artifactId>bucket4j-core</artifactId>
<version>8.10.1</version>
</dependency>
Bucket bucket = Bucket.builder()
.addLimit(Bandwidth.simple(20, Duration.ofSeconds(1)))
.build();
@GetMapping("/orders")
public ResponseEntity<?> getOrders() {
if (!bucket.tryConsume(1)) {
return ResponseEntity.status(429).body("Zu viele Anfragen");
}
return ResponseEntity.ok(orderService.findAll());
}
Hinweis: Rate Limiting nach IP-Adresse kann durch gefälschte IPs oder verteilte Botnets umgangen werden. Bei großflächigem DDoS musst du den LB mit CDN/WAF davor kombinieren; der LB ist nur die zweite Verteidigungslinie.
8. Gesundheitsüberwachung des Backends (Health Monitoring)
Anders als Punkt 5 (Reaktion auf fehlgeschlagene Anfragen) ist Health Monitoring, wenn der LB aktiv regelmäßig einen Endpoint aufruft, um zu prüfen, ob der Server noch läuft — das heißt Active Health Check.
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity<String> health() {
boolean dbUp = checkDatabaseConnection();
if (!dbUp) {
return ResponseEntity.status(503).body("DB_DOWN");
}
return ResponseEntity.ok("OK");
}
private boolean checkDatabaseConnection() {
// überprüfe Connection Pool, gib true/false zurück
return true;
}
}
Mit Spring Boot Actuator hast du einen ähnlichen Endpoint bereits ohne manuelle Arbeit:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management.endpoints.web.exposure.include=health
management.endpoint.health.show-details=always
Der LB (oder Kubernetes) ruft /actuator/health alle paar Sekunden auf:
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
periodSeconds: 5
failureThreshold: 3
Schreib einen Test, um sicherzustellen, dass der Endpoint richtig antwortet, wenn die DB ausfällt:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class HealthControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void shouldReturn503WhenDatabaseDown() {
// simuliere DB-Fehler über Test-Profil oder Mock-Bean
ResponseEntity<String> response =
restTemplate.getForEntity("/health", String.class);
assertThat(response.getStatusCode().value()).isIn(200, 503);
}
}
Dieser Test stellt sicher, dass der Endpoint /health immer einen gültigen Status (200 oder 503) zurückgibt, ohne eine Exception zu werfen — denn wenn die Health Check selbst fehlschlägt, versteht der LB fälschlicherweise, dass der Server down ist und entfernt versehentlich eine gesunde Instanz.
Hinweis: Der Health-Check-Endpoint muss leicht und schnell sein (unter ein paar hundert ms). Falls er viele Tabellen abfragt oder andere Services aufruft, kann der Health Check selbst zum Timeout-Verursacher werden und der LB entfernt ihn zu Unrecht.
9. Fazit
Ein Load Balancer ist nicht nur ein „Lastverteiler” — er spielt auch eine Rolle bei SSL-Entlastung, Session-Verwaltung, Fehlererkennung, horizontaler Skalierung und als erste Verteidigungslinie gegen DDoS. Bei der Systemgestaltung solltest du klar bestimmen, welche der 7 Funktionen du brauchst, um die richtigen Funktionen beim Konfigurieren des LB auszuwählen — nginx, HAProxy, AWS ALB oder Kubernetes Service unterstützen fast alle diese Use Cases, unterscheiden sich aber in der Konfiguration.
Abschließende Empfehlung: Verlagere nicht alle Verantwortung auf einen einzelnen LB. Die Kombination aus aktiven Health Checks, Rate Limiting und Session-Externalisierung macht dein System sowohl skalierbarer als auch fehlertoleranter, als wenn du nur Round Robin aktivierst und es dabei lässt.