Load-Balancing / Session Affinity / Sticky Sessions
Load-Balancing / Session Affinity / Sticky Sessions
Wenn das jadice web toolkit aufgrund der zu erwartenden Last (siehe Dimensionierung und JVM-Konfiguration) über mehrere Instanzen verteilt wird, muss der Load-Balancer so konfiguriert sein, dass alle Anfragen eines Benutzers auf derselben Instanz landen (Session Affinity, „Sticky Sessions“). Für den Produktivbetrieb mit mehreren Instanzen ist das zwingend einzurichten.
Was ohne Session Affinity passiert
Der Viewer funktioniert auch ohne Session Affinity – deshalb fällt eine fehlende Konfiguration in Tests oft nicht auf. Landet eine Anfrage auf einer Instanz, die das Dokument noch nicht kennt, lädt diese es über die Wiederherstellung von Dokumenten erneut. Ohne Session Affinity geschieht das nicht nur im Ausnahmefall, sondern regelmäßig:
- Jedes Dokument wird im ungünstigsten Fall auf jeder Instanz einmal aus dem Archiv geholt und geparst. Last auf Archiv, CPU und Netzwerk vervielfacht sich mit der Zahl der Instanzen.
- Dasselbe Dokument liegt redundant in den Caches aller Instanzen. Der Cache fasst damit effektiv weniger Dokumente, und Dokumente werden früher verdrängt.
- Benutzer erleben beim Blättern wiederholte Ladeverzögerungen, sobald eine Anfrage eine andere Instanz trifft.
- Ist der Tile-Security-Filter auf fail-closed gestellt
(
webtoolkit.tileSecurityFilterFailClosed: true, siehe Konfiguration), werden Tile-Requests auf einer anderen Instanz zunächst mit HTTP 401 abgewiesen.
Die Wiederherstellung ist als Failover für Neustart und Ausfall einer Instanz gedacht, nicht als Ersatz für Session Affinity.
Die Metrik jwt.recover.document zählt pro Instanz, wie oft Dokumente wiederhergestellt wurden
(siehe Metriken: Laden von Dokumenten). Steigt sie
im Normalbetrieb – ohne Neustart oder Ausfall einer Instanz – deutlich an, greift die Session
Affinity nicht, oder der Cache ist zu klein dimensioniert.
Kubernetes und OpenShift
In Kubernetes erfolgt die Lastverteilung meist durch einen Ingress-Controller oder ein Gateway.
Session Affinity muss dort konfiguriert werden; wie, hängt vom eingesetzten Produkt ab (in der
Regel cookie-basiert). sessionAffinity: ClientIP am Service greift nur, wenn die Anfragen
direkt über den Service verteilt werden, und ist hinter NAT oder einem vorgelagerten Proxy
unzuverlässig, weil viele Benutzer dieselbe Quell-IP haben.
Beispiel: HAProxy
Dieses Kapitel soll beispielhaft zeigen, wie per HAProxy ein Software-Load-Balancing mit Session Affinity erreicht
werden kann. Hinweis zu den Beispielen: Der Healthcheck-Pfad option httpchk HEAD /enterprise/ stammt aus der
Demo-Anwendung — verwenden Sie hier den Kontextpfad Ihrer eigenen Integration.
Sticky Sessions per JSESSIONID-Cookie
Wenn die Integration die Http-Session (Teil der Java EE Spezifikation) verwendet, also z.B. request.getSession(),
wird beim Client das JSESSIONID-Cookie gesetzt. Dieses kann von HAProxy verwendet werden, um einen Benutzer stets
auf denselben Server zu leiten.
defaults
mode http
log global
option httplog
option http-server-close
option dontlognull
retries 3
timeout client 25s
timeout connect 5s
timeout server 25s
timeout tunnel 3600s
timeout http-keep-alive 1s
timeout http-request 15s
timeout queue 30s
timeout tarpit 60s
default-server inter 3s rise 2 fall 3
option forwardfor
frontend jwt_web
bind *:8000
mode http
default_backend jwt_back
backend jwt_back
option httpchk HEAD /enterprise/
balance roundrobin
cookie JSESSIONID prefix nocache
server websrv1 192.168.0.2:8080 check cookie s1
server websrv2 192.168.0.3:8080 check cookie s2
Sticky Sessions mit eigenem Cookie
Wenn die Anwendung keine Http-Session verwendet, existiert möglicherweise kein Cookie, um den Client eindeutig zu
identifizieren. In diesem Fall kann HAProxy ein eigenes Cookie erzeugen und verwalten (in dem Beispiel ist der Name
des Cookie SERVERID)
defaults
mode http
log global
option httplog
option http-server-close
option dontlognull
retries 3
timeout client 25s
timeout connect 5s
timeout server 25s
timeout tunnel 3600s
timeout http-keep-alive 1s
timeout http-request 15s
timeout queue 30s
timeout tarpit 60s
default-server inter 3s rise 2 fall 3
option forwardfor
frontend jwt_web
bind *:8000
mode http
default_backend jwt_back
backend jwt_back
option httpchk HEAD /enterprise/
balance roundrobin
cookie SERVERID insert indirect nocache
server websrv1 192.168.0.2:8080 check cookie s1
server websrv2 192.168.0.3:8080 check cookie s2