Sticky Sessions mit Apache APISIX – Theorie

Nicolas Fränkel

Nicolas Fränkel

July 27, 2023

Technology

Sticky Sessions, auch bekannt als Session Affinity, ist ein Mechanismus, bei dem eine Routing-Komponente, die als Fassade fungiert, eine Anfrage immer an denselben zugrunde liegenden Upstream-Knoten weiterleitet. In diesem Beitrag werde ich den Grund für Sticky Sessions, verfügbare Alternativen und deren Implementierung über Apache APISIX beschreiben.

Warum Sticky Sessions?

Sticky Sessions wurden populär, als wir den Zustand auf dem Upstream-Knoten und nicht in der Datenbank speicherten. Ich werde das Beispiel eines vereinfachten E-Commerce-Shops verwenden, um dies näher zu erläutern.

Die grundlegende Struktur eines kleinen E-Commerce-Shops kann aus einer Webanwendung und einer Datenbank bestehen.

Grundlegende Architektur einer E-Commerce-App

Wenn das Geschäft erfolgreich ist, wird es wachsen, und Sie müssen diese Architektur irgendwann skalieren. Sobald Sie nicht mehr vertikal skalieren können (größere Maschinen), müssen Sie horizontal skalieren (mehr Knoten). Mit zusätzlichen App-Knoten benötigen Sie auch einen Load-Balancer-Mechanismus vor den Web-App-Knoten, um die Last unter ihnen zu verteilen.

Load-Balancing-Architektur für zusätzliche Knoten

Jedes Mal in die Datenbank zu gehen, ist ein teurer Vorgang. Es ist in Ordnung für Daten, auf die selten zugegriffen wird. Allerdings möchten wir den Inhalt des Warenkorbs bei jeder Anfrage anzeigen. Es gibt einige Alternativen, um die Dinge zu beschleunigen. Wenn wir davon ausgehen, dass die Web-App Server-Side Rendering verwendet, ist die klassische Lösung, die Warenkorbdaten im Speicher des Web-App-Knotens zu halten.

Wenn wir jedoch den Warenkorb von Benutzer X auf Knoten 1 speichern, müssen wir sicherstellen, dass jede Anfrage von Benutzer X an denselben Knoten weitergeleitet wird. Andernfalls wird es so aussehen, als hätten sie den Inhalt ihres Warenkorbs verloren. Sticky Sessions oder Session Affinity ist der Mechanismus, der denselben Benutzer konsistent an denselben Knoten weiterleitet.

Einschränkungen von Sticky Sessions

Bevor ich fortfahre, muss ich eine wesentliche Einschränkung von Sticky Sessions erklären. Wenn der Web-App-Knoten, der die Daten speichert, aus irgendeinem Grund ausfällt, sind die Daten unwiederbringlich verloren. Für das oben genannte E-Commerce-Szenario bedeutet dies, dass Benutzer gelegentlich ihren Warenkorb verlieren, was aus geschäftlicher Sicht nicht akzeptabel ist.

Aus diesem Grund müssen Sticky Sessions Hand in Hand mit Session Replication gehen: Daten, die auf einem Knoten gespeichert sind, müssen kopiert und mit allen anderen Knoten synchronisiert werden.

Während Session Replication in allen Tech-Stacks existiert, gibt es keine entsprechende Spezifikation. Ich bin mit der JVM vertraut, daher hier ein paar Optionen:

  • Tomcat bietet Session Replication out-of-the-box
  • Hazelcast bietet eine geclusterte In-Memory-Lösung, die Sie auf verschiedenen Ebenen integrieren können
  • Spring Session ist eine Abstraktionsschicht über spezifischen Lösungen

Wenn Daten auf allen Knoten (oder einem Remote-Cluster) repliziert werden, könnte man denken, dass Sticky Sessions nicht mehr benötigt werden. Das ist wahr, wenn man nur die Verfügbarkeit und nicht die Leistung berücksichtigt. Es geht um Datenlokalität: Das Abrufen von Daten auf dem aktuellen Knoten ist schneller als das Abrufen von Daten von einem anderen Ort über das Netzwerk.

Sticky Sessions in Apache APISIX

Sticky Sessions sind ein Muss für jeden Load Balancer, Reverse Proxy und API Gateway, der seinen Namen verdient. Allerdings muss ich zugeben, dass die Dokumentation von Apache APISIX einen einfachen Einstieg in das Thema benötigt.

Apache APISIX bindet eine Route an ein Upstream. Ein Upstream besteht aus einem oder mehreren Knoten. Wenn eine Anfrage auf die Route passt, muss Apache APISIX unter allen verfügbaren Knoten auswählen, an welche die Anfrage weitergeleitet wird. Standardmäßig ist der Algorithmus ein gewichtetes Round-Robin. Round-Robin verwendet einen Knoten nach dem anderen, und nach dem letzten kehrt es zum ersten zurück. Bei einem gewichteten Round-Robin beeinflusst das Gewicht, wie viele Anfragen Apache APISIX an einen Knoten weiterleitet, bevor es zum nächsten wechselt.

Es stehen jedoch auch andere Algorithmen zur Verfügung:

Consistent Hashing ermöglicht die Weiterleitung an denselben Knoten basierend auf einem Wert: einer NGINX-Variablen, einem HTTP-Header, einem Cookie usw.

Denken Sie daran, dass HTTP ein zustandsloses Protokoll ist, daher setzen Anwendungsserver beim ersten Antwort ein Cookie, um den Benutzer über HTTP-Anfragen hinweg zu verfolgen. Das nennen wir eine "Session". Wir müssen den Namen des zugrunde liegenden Session-Cookies kennen. Unterschiedliche Anwendungsserver verwenden unterschiedliche Cookies:

  • JSESSIONID für JVM-basierte Server
  • PHPSESSID für PHP
  • ASPSESSIONID für ASP.Net
  • usw.

Ich werde einen regulären Tomcat verwenden, daher ist das Session-Cookie JSESSIONID. Daher sieht die Apache APISIX-Dokumentation für zwei Knoten wie folgt aus:

routes:
  - uri: /*
    upstream:
      nodes:
        "tomcat1:8080": 1            #1
        "tomcat2:8080": 1            #1
      type: chash                    #2
      hash_on: cookie                #3
      key: cookie_JSESSIONID         #4
  1. Definieren Sie die Upstream-Knoten
  2. Wählen Sie den Consistent-Hashing-Algorithmus
  3. Hash auf Cookie
  4. Definieren Sie, auf welches Cookie gehasht werden soll

Fazit

In diesem Beitrag haben wir Sticky Sessions detailliert beschrieben, dass Sie immer Session Replication mit Sticky Sessions verwenden sollten, und wie Sie Sticky Sessions in Apache APISIX implementieren können.

Um weiterzugehen:

Tags: