# Load balancing met Nginx over meerdere app-servers

> Verdeel het verkeer van een site over meerdere app-servers met een Nginx-load balancer in Vimonto Deploy: methoden, gewichten, reserveservers, HTTPS en IP.

**Load balancing** verdeelt de bezoekers van één site over meerdere app-servers. Een load balancer-server staat ervoor: je domein wijst ernaar, hij antwoordt op HTTP en HTTPS, en Nginx stuurt elk verzoek door naar een van de app-servers erachter. Reageert een app-server niet meer, dan nemen de andere het over.

In Vimonto Deploy is een load balancer een eigen server met een load-balanced site erop. Op de pagina **Load balancing** van die site kies je de app-servers, hoe het verkeer over ze wordt verdeeld, en welke alleen bijspringen als de andere uitvallen.

![De pagina Load balancing van een site met de balanceermethode, twee app-servers en hun gewichten](https://ops.vimonto.com/docs-media/nl/site-load-balancing.webp?v=161e760d "Een load-balanced site")

## Hoe werkt load balancing?

| Onderdeel | Wat het doet |
|---|---|
| **Load balancer-server** | Een server van het type **Load balancer**, met alleen Nginx. De DNS van je domein wijst ernaar. |
| **Load-balanced site** | De site op de load balancer, gemaakt met de preset **Load balancer**. Hij heeft het domein, het certificaat en de lijst met app-servers, maar geen code. |
| **App-servers** | App- of webservers in je organisatie, elk met een site voor hetzelfde domein. Ze draaien je code en worden gewoon gedeployd. |

Een bezoeker maakt verbinding met de load balancer. Nginx kiest daar een app-server, stuurt het verzoek door met de oorspronkelijke `Host`- en `X-Forwarded-*`-headers, en stuurt het antwoord terug. De app-servers zien het IP-adres van de bezoeker en of die HTTPS gebruikte, omdat hun sites deze load balancer vertrouwen (zie [wat de app-servers nodig hebben](#wat-hebben-de-app-servers-nodig)).

## Een load balancer instellen

1. [Maak een server aan](https://ops.vimonto.com/docs/nl/servers/create-a-server) van het type **Load balancer**. Die krijgt alleen Nginx; zie [servertypes](https://ops.vimonto.com/docs/nl/servers/server-types).
2. Zorg dat elke app-server een site voor je domein heeft, bijvoorbeeld `shop.example.com`, en dat die gedeployd is. Gebruik hetzelfde domein of voeg het toe als alias onder [domeinen en SSL](https://ops.vimonto.com/docs/nl/sites/domains-and-ssl).
3. Klik op de pagina **Sites** van de load balancer op **Nieuwe site** en kies **Load balancer** onder **Load balancing**.
4. Vul met **Eigen domein gebruiken** hetzelfde domein in en klik op **Site aanmaken**. Een load-balanced site heeft geen repository, geen database en geen deploys.

> [!NOTE]
> De load balancer heeft een eigen domein nodig voordat je app-servers kunt toevoegen: de sites op je app-servers kunnen niet antwoorden voor een `on-deploy.link`-naam. Zolang hij er geen heeft, meldt de pagina Load balancing **Voeg eerst een domein toe**. Heeft hij er een, dan blijven verzoeken die binnenkomen op zijn `on-deploy.link`-adres gewoon werken: de load balancer stuurt ze door met je eigen domein als `Host`.
5. Open de pagina **Load balancing** van de nieuwe site en voeg je app-servers toe (zie hieronder).
6. Laat de DNS van het domein naar het IP-adres van de load balancer wijzen, en zet HTTPS aan op de site van de load balancer onder [domeinen en SSL](https://ops.vimonto.com/docs/nl/sites/domains-and-ssl).

Tot je een app-server toevoegt, antwoordt de load balancer op elk verzoek met `503 Service Unavailable`, en het overzicht van de site meldt **Nog geen appservers. Bezoekers krijgen een 503 tot je er een toevoegt.**

Een load balancer-server bevat alleen load-balanced sites, en de preset **Load balancer** komt alleen op een load balancer-server: het formulier toont alleen de servers die passen.

## Een app-server toevoegen

1. Klik op de pagina **Load balancing** van de site op **Server toevoegen**.
2. Kies de **Server**. De lijst bevat de actieve app- en webservers van je organisatie waar je toegang toe hebt.
3. Stel de **Poort** in waarop de site van de app-server luistert: standaard `80`.
4. Stel het **Gewicht** in, van 1 tot 100: een server met gewicht 3 krijgt drie keer zoveel verzoeken als een server met gewicht 1.
5. Zet **Reserveserver** aan als deze server alleen verkeer moet krijgen als de andere servers uitgevallen zijn.
6. Klik op **Server toevoegen**.

De load balancer bereikt de app-server via het [privénetwerk](https://ops.vimonto.com/docs/nl/servers/network) als beide servers op hetzelfde netwerk zitten, en anders via het publieke IP-adres. De lijst **Servers** toont elke app-server met het adres en de poort die de load balancer gebruikt, het gewicht en een label **Reserve**.

Een server kan meer dan eens worden toegevoegd, op verschillende poorten.

## Een app-server bewerken

Klik naast de server op **Bewerken**, wijzig de **Poort**, het **Gewicht** of de instelling **Reserveserver** en klik op **Opslaan**. De server zelf blijft dezelfde; wil je een andere gebruiken, voeg die dan toe en haal deze eruit. De wijziging wordt meteen toegepast.

## De balanceermethode kiezen

Klik onder **Methode** op een van de drie opties. De wijziging wordt meteen toegepast.

| Methode | Hoe Nginx een app-server kiest |
|---|---|
| **Round robin** (standaard) | Elke server om de beurt, naar gewicht. |
| **Minste verbindingen** | De server met de minste open verbindingen, voor verzoeken die heel verschillend lang duren. |
| **IP-hash** | Elke bezoeker blijft bij één server, op basis van zijn IP-adres. Gebruik dit alleen als je app iets op één server bewaart. |

Nginx accepteert geen reserveservers samen met **IP-hash**, dus Vimonto Deploy laat je ze niet combineren. Is IP-hash gekozen, dan kun je **Reserveserver** niet aanzetten en meldt het formulier **IP-hash werkt niet met reserveservers. Kies eerst een andere methode.** Staat er een reserveserver in de lijst, dan wordt de keuze voor IP-hash geweigerd met **IP-hash werkt niet met reserveservers**: bewerk eerst je reserveservers zodat het geen reserve meer is.

## Wat gebeurt er als een app-server uitvalt?

De load balancer controleert de app-servers via de verzoeken die hij stuurt; er zijn geen aparte health checks. Mislukt een verzoek aan een app-server met een verbindingsfout, een time-out of een `502`, `503` of `504`, dan probeert Nginx de volgende server, zodat de bezoeker toch een antwoord krijgt. Na 3 fouten binnen 10 seconden krijgt de server 10 seconden geen verkeer, en daarna probeert Nginx hem opnieuw.

Reserveservers krijgen alleen verkeer als alle andere servers onbereikbaar zijn.

## Een app-server eruit halen

Klik naast de server op **Eruit halen** en bevestig. De load balancer stuurt er geen verkeer meer naartoe, en de sites op die server vertrouwen de load balancer niet meer (zie hieronder). Verder verandert er niets op de server, en de site blijft op zijn eigen adres werken.

Dezelfde opruiming gebeurt vanzelf als je de load-balanced site of de load balancer-server verwijdert: de sites op de app-servers vertrouwen hem dan niet meer. Verwijder je een app-server, dan stuurt de load balancer er geen verkeer meer naartoe.

## Wat hebben de app-servers nodig?

Elke wijziging op de pagina Load balancing schrijft ook de Nginx-configuratie van de sites op de app-servers die hetzelfde domein serveren. Die sites vertrouwen dan de load balancer, en alleen die:

- **Het IP-adres van de bezoeker.** Nginx haalt het adres uit `X-Forwarded-For`, maar alleen als het verzoek van de load balancer komt (`set_real_ip_from`). Je app ziet het IP-adres van de bezoeker als remote address, zonder eigen proxy-instellingen.
- **HTTPS.** Ontving de load balancer het verzoek over HTTPS, dan krijgt PHP `HTTPS=on` en een Node.js-app `X-Forwarded-Proto: https`. Laravel en andere frameworks maken dan `https://`-links zonder trusted-proxyconfiguratie.

Verzoeken van ergens anders kunnen deze headers niet vervalsen. Haal je een server eruit, of verwijder je de load-balanced site of de load balancer, dan verdwijnt het vertrouwen weer. Een site met een [eigen Nginx-configuratie](https://ops.vimonto.com/docs/nl/sites/nginx#wat-verandert-er-als-je-je-eigen-configuratie-gebruikt) blijft ongemoeid; voeg deze regels dan zelf toe.

Je app moet ook op meerdere servers tegelijk werken:

- Bewaar **sessies en cache** in Redis of de database, op een gedeelde [database- of cacheserver](https://ops.vimonto.com/docs/nl/servers/server-types), niet in bestanden op één server. Voor Laravel betekent dat `SESSION_DRIVER` en `CACHE_STORE` op `redis` of `database` in de [.env](https://ops.vimonto.com/docs/nl/sites/environment) van elke app-server, met dezelfde Redis of database.
- Bewaar **uploads** in object storage zoals S3, niet in `storage/` van één server.
- **Deploy** de site van elke app-server. Elke app-server heeft zijn eigen release en deploy, dus deploy ze allemaal als je een nieuwe versie uitbrengt.
- Draai de **scheduler** op maar één app-server, tenzij je geplande taken veilig meer dan eens kunnen draaien.

HTTPS hoort op de load balancer, die gewoon HTTP praat met de app-servers. Een site op een app-server mag wel een eigen certificaat hebben, bijvoorbeeld om hem rechtstreeks te bereiken: hij stuurt gewoon HTTP door naar HTTPS voor iedereen behalve de load balancer, die hij over gewone HTTP serveert, dus er ontstaat geen doorverwijzingslus.

## HTTPS op de load balancer

De load-balanced site heeft een eigen pagina **Domeinen en SSL**. Omdat je domein naar de load balancer wijst, vraag je daar een gratis Let's Encrypt-certificaat aan, zoals bij elke site, en dat wordt automatisch vernieuwd. De load balancer antwoordt dan op HTTPS, stuurt HTTP door naar HTTPS en geeft de verzoeken over HTTP door aan de app-servers, met `X-Forwarded-Proto: https`.

Het verkeer tussen de load balancer en de app-servers is niet versleuteld. Zet ze op hetzelfde [privénetwerk](https://ops.vimonto.com/docs/nl/servers/network), zodat het binnen het netwerk van je provider blijft.

## Hoe de Nginx-configuratie eruitziet

De configuratie van de load-balanced site heeft een `upstream`-block met de app-servers en een `location` die verzoeken daarnaartoe doorstuurt:

```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;
    }
}
```

Verbindingen met de app-servers blijven open en worden hergebruikt, en WebSocket-verbindingen worden doorgegeven. Elke wijziging wordt als achtergrondtaak geschreven, getest met `nginx -t` en pas daarna geladen; keurt Nginx hem af, dan blijft de vorige configuratie actief. Zie [Nginx](https://ops.vimonto.com/docs/nl/sites/nginx).

Heb je op de Nginx-pagina van de load-balanced site een eigen configuratie opgeslagen, dan worden wijzigingen op de pagina Load balancing opgeslagen maar niet toegepast: je ziet **Opgeslagen, niet toegepast**. Zet de standaardconfiguratie terug op de Nginx-pagina om ze te gebruiken.

## Wat heeft een load-balanced site nog meer?

De zijbalk van een load-balanced site toont **Overzicht**, **Load balancing**, **Domeinen en SSL**, **Logs**, **Nginx** en **Instellingen**. Hij heeft geen pagina Deployments of Omgeving, omdat hij geen code heeft. Zijn pagina **Instellingen** heeft alleen **Site verwijderen**: er is geen webmap, deployinstelling of isolatie te kiezen. De siteheader toont naar hoeveel app-servers hij verkeer doorstuurt.

- **Logs** toont de eigen Nginx-error- en requestlogs van de load balancer. De logs van je app staan op de sites van de app-servers.
- **Wachtwoordbeveiliging**, in het frameworkmenu van de siteheader, beveiligt alle app-servers achter de load balancer in één keer. Het is de enige [sitefunctie](https://ops.vimonto.com/docs/nl/sites/site-features) van een load-balanced site.

Elk lid kan de pagina Load balancing zien. Servers toevoegen, bewerken en eruit halen en de methode wijzigen vereist het recht om sites te beheren; zie [leden en rollen](https://ops.vimonto.com/docs/nl/organization/members-and-roles). Elke wijziging wordt vastgelegd in het [auditlog](https://ops.vimonto.com/docs/nl/organization/audit-log).

## Veelgestelde vragen

### Hoeveel app-servers kan ik achter een load balancer zetten?

Zoveel als je wilt. Elke server is een regel in het `upstream`-block.

### Heb ik sticky sessions nodig?

Niet als sessies in Redis of de database staan, die elke app-server leest. Dan werkt **Round robin** of **Minste verbindingen** het best. Gebruik **IP-hash** alleen als er echt iets op één server staat.

### Kan ik één load balancer voor meerdere domeinen gebruiken?

Ja. Maak op de load balancer per domein een load-balanced site aan, elk met zijn eigen app-servers.

### Waarom lijkt mijn domein op de app-servers ergens anders naartoe te wijzen?

Omdat het naar de load balancer wijst, zoals het hoort. Alleen de site van de load balancer heeft het DNS-record en het certificaat nodig.
