# Lastverteilung mit Nginx über mehrere App-Server

> Verteile den Traffic deiner Site mit einem Nginx-Load-Balancer in Vimonto Deploy auf mehrere App-Server: Methoden, Gewichte, Reserveserver, HTTPS, Besucher-IP.

**Lastverteilung** verteilt die Besucher einer Site auf mehrere App-Server. Davor sitzt ein Load-Balancer-Server: Deine Domain zeigt auf ihn, er antwortet über HTTP und HTTPS, und Nginx leitet jeden Request an einen der App-Server dahinter weiter. Antwortet ein App-Server nicht mehr, übernehmen die anderen.

In Vimonto Deploy ist ein Load Balancer ein eigener Server mit einer lastverteilten Site darauf. Auf der Seite **Lastverteilung** dieser Site wählst du die App-Server, legst fest, wie der Traffic zwischen ihnen aufgeteilt wird, und bestimmst, welche nur einspringen, wenn die anderen ausfallen.

![Die Seite Lastverteilung einer Site mit der Verteilungsmethode, zwei App-Servern und ihren Gewichten](https://ops.vimonto.com/docs-media/de/site-load-balancing.webp?v=161e760d "Eine lastverteilte Site")

## Wie funktioniert Lastverteilung?

| Teil | Was er tut |
|---|---|
| **Load-Balancer-Server** | Ein Server vom Typ **Load Balancer**, nur mit Nginx. Das DNS deiner Domain zeigt auf ihn. |
| **Lastverteilte Site** | Die Site auf dem Load Balancer, angelegt aus der Vorlage **Load Balancer**. Sie hat die Domain, das Zertifikat und die Liste der App-Server, aber keinen Code. |
| **App-Server** | App- oder Webserver in deiner Organisation, jeder mit einer Site für dieselbe Domain. Sie führen deinen Code aus und werden wie gewohnt deployt. |

Ein Besucher verbindet sich mit dem Load Balancer. Nginx wählt dort einen App-Server, leitet den Request mit dem ursprünglichen `Host` und den `X-Forwarded-*`-Headern weiter und schickt die Antwort zurück. Die App-Server sehen die IP-Adresse des Besuchers und ob er HTTPS genutzt hat, weil ihre Sites diesem Load Balancer vertrauen (siehe [was die App-Server brauchen](#was-brauchen-die-app-server)).

## Einen Load Balancer einrichten

1. [Lege einen Server](https://ops.vimonto.com/docs/de/servers/create-a-server) vom Typ **Load Balancer** an. Er bekommt nur Nginx; siehe [Servertypen](https://ops.vimonto.com/docs/de/servers/server-types).
2. Stelle sicher, dass jeder App-Server eine Site für deine Domain hat, zum Beispiel `shop.example.com`, und dass sie deployt ist. Verwende dieselbe Domain oder füge sie unter [Domains und SSL](https://ops.vimonto.com/docs/de/sites/domains-and-ssl) als Alias hinzu.
3. Klicke auf der Seite **Sites** des Load Balancers auf **Neue Site** und wähle **Load Balancer** unter **Lastverteilung**.
4. Gib mit **Eigene Domain verwenden** dieselbe Domain ein und klicke auf **Site anlegen**. Eine lastverteilte Site hat kein Repository, keine Datenbank und keine Deploys.

> [!NOTE]
> Der Load Balancer braucht eine eigene Domain, bevor du App-Server hinzufügen kannst: Die Sites auf deinen App-Servern können nicht für einen `on-deploy.link`-Namen antworten. Solange er keine hat, zeigt die Seite Lastverteilung **Füge zuerst eine Domain hinzu**. Sobald er eine hat, funktionieren Requests, die über seine `on-deploy.link`-Adresse hereinkommen, weiterhin: Der Load Balancer reicht sie mit deiner eigenen Domain als `Host` weiter.
5. Öffne die Seite **Lastverteilung** der neuen Site und füge deine App-Server hinzu (siehe unten).
6. Lass das DNS der Domain auf die IP-Adresse des Load Balancers zeigen und aktiviere HTTPS auf der Site des Load Balancers unter [Domains und SSL](https://ops.vimonto.com/docs/de/sites/domains-and-ssl).

Bis du einen App-Server hinzufügst, beantwortet der Load Balancer jeden Request mit `503 Service Unavailable`, und die Übersicht der Site zeigt **Noch keine App-Server. Besucher bekommen einen 503, bis du einen hinzufügst.**

Ein Load-Balancer-Server nimmt nur lastverteilte Sites auf, und die Vorlage **Load Balancer** lässt sich nur auf einem Load-Balancer-Server anlegen: Das Formular listet nur die passenden Server auf.

## Einen App-Server hinzufügen

1. Klicke auf der Seite **Lastverteilung** der Site auf **Server hinzufügen**.
2. Wähle den **Server**. Die Liste enthält die aktiven App- und Webserver deiner Organisation, auf die du Zugriff hast.
3. Lege den **Port** fest, auf dem die Site des App-Servers lauscht: standardmäßig `80`.
4. Lege das **Gewicht** fest, von 1 bis 100: Ein Server mit Gewicht 3 bekommt dreimal so viele Requests wie einer mit Gewicht 1.
5. Schalte **Reserveserver** ein, wenn dieser Server nur Traffic bekommen soll, wenn die anderen Server ausgefallen sind.
6. Klicke auf **Server hinzufügen**.

Der Load Balancer erreicht den App-Server über das [private Netzwerk](https://ops.vimonto.com/docs/de/servers/network), wenn beide Server im selben sind, sonst über seine öffentliche IP-Adresse. Die Liste **Server** zeigt jeden App-Server mit der Adresse und dem Port, die der Load Balancer verwendet, seinem Gewicht und einem Badge **Reserve**.

Ein Server kann mehrmals hinzugefügt werden, auf verschiedenen Ports.

## Einen App-Server bearbeiten

Klicke neben dem Server auf **Bearbeiten**, ändere seinen **Port**, sein **Gewicht** oder die Einstellung **Reserveserver** und klicke auf **Speichern**. Der Server selbst bleibt derselbe; um einen anderen zu verwenden, füge ihn hinzu und nimm diesen heraus. Die Änderung wird sofort angewendet.

## Die Verteilungsmethode wählen

Klicke unter **Methode** auf eine der drei Optionen. Die Änderung wird sofort angewendet.

| Methode | Wie Nginx einen App-Server wählt |
|---|---|
| **Round Robin** (Standard) | Jeden Server der Reihe nach, nach Gewicht. |
| **Wenigste Verbindungen** | Den Server mit den wenigsten offenen Verbindungen, für Requests, die sehr unterschiedlich lange dauern. |
| **IP-Hash** | Jeder Besucher bleibt anhand seiner IP-Adresse bei einem Server. Nutze das nur, wenn deine App etwas auf einem Server ablegt. |

Nginx akzeptiert keine Reserveserver zusammen mit **IP-Hash**, deshalb lässt Vimonto Deploy dich beides nicht kombinieren. Ist IP-Hash gewählt, lässt sich **Reserveserver** nicht einschalten, und das Formular zeigt **IP-Hash funktioniert nicht mit Reserveservern. Wähle zuerst eine andere Methode.** Steht ein Reserveserver in der Liste, wird die Wahl von IP-Hash mit **IP-Hash funktioniert nicht mit Reserveservern** abgelehnt: Bearbeite zuerst deine Reserveserver, sodass sie keine Reserve mehr sind.

## Was passiert, wenn ein App-Server ausfällt?

Der Load Balancer prüft die App-Server über die Requests, die er schickt; separate Health Checks gibt es nicht. Schlägt ein Request an einen App-Server mit einem Verbindungsfehler, einem Timeout oder einem `502`, `503` oder `504` fehl, versucht Nginx den nächsten Server, sodass der Besucher trotzdem eine Antwort bekommt. Nach 3 Fehlern innerhalb von 10 Sekunden bekommt der Server 10 Sekunden lang keinen Traffic, danach versucht Nginx es erneut.

Reserveserver bekommen nur Traffic, wenn alle anderen Server nicht erreichbar sind.

## Einen App-Server herausnehmen

Klicke neben dem Server auf **Herausnehmen** und bestätige. Der Load Balancer schickt keinen Traffic mehr an ihn, und die Sites auf diesem Server vertrauen dem Load Balancer nicht mehr (siehe unten). Sonst ändert sich nichts auf dem Server, und seine Site funktioniert unter ihrer eigenen Adresse weiter.

Dieselbe Bereinigung geschieht von selbst, wenn du die lastverteilte Site oder den Load-Balancer-Server löschst: Die Sites auf den App-Servern vertrauen ihm dann nicht mehr. Löschst du einen App-Server, schickt der Load Balancer keinen Traffic mehr an ihn.

## Was brauchen die App-Server?

Jede Änderung auf der Seite Lastverteilung schreibt auch die Nginx-Konfiguration der Sites auf den App-Servern, die dieselbe Domain ausliefern. Diese Sites vertrauen dann dem Load Balancer, und nur ihm:

- **Die IP-Adresse des Besuchers.** Nginx übernimmt die Adresse aus `X-Forwarded-For`, aber nur, wenn der Request vom Load Balancer kommt (`set_real_ip_from`). Deine App sieht die IP-Adresse des Besuchers als Remote-Adresse, ohne eigene Proxy-Einstellungen.
- **HTTPS.** Hat der Load Balancer den Request über HTTPS empfangen, bekommt PHP `HTTPS=on` und eine Node.js-App `X-Forwarded-Proto: https`. Laravel und andere Frameworks erzeugen dann `https://`-Links ohne Trusted-Proxy-Konfiguration.

Requests von anderswo können diese Header nicht fälschen. Nimmst du einen Server heraus oder löschst du die lastverteilte Site oder den Load Balancer, wird das Vertrauen wieder entfernt. Eine Site mit einer [eigenen Nginx-Konfiguration](https://ops.vimonto.com/docs/de/sites/nginx#was-ändert-sich-wenn-du-deine-eigene-konfiguration-verwendest) bleibt unangetastet; ergänze diese Zeilen dort selbst.

Deine App muss außerdem auf mehreren Servern gleichzeitig funktionieren:

- Lege **Sessions und Cache** in Redis oder der Datenbank ab, auf einem gemeinsamen [Datenbank- oder Cache-Server](https://ops.vimonto.com/docs/de/servers/server-types), nicht in Dateien auf einem Server. Bei Laravel heißt das: `SESSION_DRIVER` und `CACHE_STORE` stehen in der [.env](https://ops.vimonto.com/docs/de/sites/environment) jedes App-Servers auf `redis` oder `database` und zeigen auf dasselbe Redis oder dieselbe Datenbank.
- Lege **Uploads** in einem Object Storage wie S3 ab, nicht in `storage/` eines einzelnen Servers.
- **Deploye** die Site jedes App-Servers. Jeder App-Server hat sein eigenes Release und seinen eigenen Deploy, also deploye alle, wenn du eine neue Version veröffentlichst.
- Lass den **Scheduler** nur auf einem App-Server laufen, es sei denn, deine geplanten Aufgaben dürfen problemlos mehrfach laufen.

HTTPS gehört auf den Load Balancer, der mit den App-Servern einfaches HTTP spricht. Eine Site auf einem App-Server darf trotzdem ein eigenes Zertifikat haben, etwa um sie direkt zu erreichen: Sie leitet einfaches HTTP für alle auf HTTPS um, außer für den Load Balancer, den sie über einfaches HTTP bedient. So entsteht keine Weiterleitungsschleife.

## HTTPS auf dem Load Balancer

Die lastverteilte Site hat ihre eigene Seite **Domains und SSL**. Weil deine Domain auf den Load Balancer zeigt, forderst du dort wie bei jeder Site ein kostenloses Let's-Encrypt-Zertifikat an, das sich automatisch verlängert. Der Load Balancer antwortet dann über HTTPS, leitet HTTP auf HTTPS weiter und reicht die Requests über HTTP an die App-Server weiter, mit `X-Forwarded-Proto: https`.

Der Traffic zwischen Load Balancer und App-Servern ist nicht verschlüsselt. Bring sie ins selbe [private Netzwerk](https://ops.vimonto.com/docs/de/servers/network), damit er im Netzwerk deines Providers bleibt.

## So sieht die Nginx-Konfiguration aus

Die Konfiguration der lastverteilten Site hat einen `upstream`-Block mit den App-Servern und eine `location`, die Requests daran weiterleitet:

```nginx
upstream site_7_servers {
    least_conn;
    server 10.0.0.3:80 weight=3 max_fails=3 fail_timeout=10s;
    server 10.0.0.4:80 max_fails=3 fail_timeout=10s backup;
    keepalive 32;
}

server {
    # listen, server_name, certificate and logs as for every site

    location / {
        proxy_pass http://site_7_servers;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade_keepalive;
        proxy_next_upstream error timeout http_502 http_503 http_504;
        proxy_read_timeout 120;
    }
}
```

Verbindungen zu den App-Servern bleiben offen und werden wiederverwendet, und WebSocket-Verbindungen werden durchgereicht. Jede Änderung wird als Hintergrundaufgabe geschrieben, mit `nginx -t` getestet und erst dann geladen; lehnt Nginx sie ab, bleibt die vorherige Konfiguration aktiv. Siehe [Nginx](https://ops.vimonto.com/docs/de/sites/nginx).

Hast du auf der Seite Nginx der lastverteilten Site eine eigene Konfiguration gespeichert, werden Änderungen auf der Seite Lastverteilung gespeichert, aber nicht angewendet: Du siehst **Gespeichert, nicht angewendet**. Stelle auf der Seite Nginx die Standardkonfiguration wieder her, um sie zu nutzen.

## Was hat eine lastverteilte Site noch?

Die Seitenleiste einer lastverteilten Site zeigt **Übersicht**, **Lastverteilung**, **Domains und SSL**, **Logs**, **Nginx** und **Einstellungen**. Sie hat keine Seite Deployments oder Umgebung, weil sie keinen Code hat. Ihre Seite **Einstellungen** hat nur **Site löschen**: Es gibt kein Web-Verzeichnis, keine Deploy-Einstellung und keine Isolation zu wählen. Der Site-Header zeigt, an wie viele App-Server sie Traffic weiterleitet.

- **Logs** zeigt die eigenen Nginx-Fehler- und Request-Logs des Load Balancers. Die Logs deiner App findest du bei den Sites auf den App-Servern.
- **Passwortschutz** im Framework-Menü des Site-Headers schützt alle App-Server hinter dem Load Balancer auf einmal. Es ist das einzige [Site-Feature](https://ops.vimonto.com/docs/de/sites/site-features) einer lastverteilten Site.

Jedes Mitglied kann die Seite Lastverteilung sehen. Server hinzufügen, bearbeiten und herausnehmen sowie die Methode ändern erfordern die Berechtigung, Sites zu verwalten; siehe [Mitglieder und Rollen](https://ops.vimonto.com/docs/de/organization/members-and-roles). Jede Änderung wird im [Audit-Log](https://ops.vimonto.com/docs/de/organization/audit-log) festgehalten.

## Häufig gestellte Fragen

### Wie viele App-Server kann ich hinter einen Load Balancer setzen?

So viele du willst. Jeder ist eine Zeile im `upstream`-Block.

### Brauche ich Sticky Sessions?

Nicht, wenn Sessions in Redis oder der Datenbank liegen, die jeder App-Server liest. Dann funktioniert **Round Robin** oder **Wenigste Verbindungen** am besten. Nutze **IP-Hash** nur, wenn wirklich etwas auf einem einzelnen Server liegt.

### Kann ich einen Load Balancer für mehrere Domains nutzen?

Ja. Lege auf dem Load Balancer pro Domain eine lastverteilte Site an, jede mit ihren eigenen App-Servern.

### Warum wird meine Domain auf den App-Servern so angezeigt, als zeige sie woandershin?

Weil sie auf den Load Balancer zeigt, wie es sein soll. Nur die Site des Load Balancers braucht den DNS-Eintrag und das Zertifikat.
