Entwickler, sprengen Sie Ihre APIs 🧨

Dieser Artikel folgt einer Präsentation, die bei den Human Talks im September 2022 gehalten wurde. Die Folien sind verfügbar ic.

Während meiner Mission bei Cinch 2021/2022 trat ich einem Team bei, das an öffentlichen APIs arbeitete, die hinter a API-Manager, Gravierte. Diese Plattform ermöglicht unter anderem die Kontrolle und Sicherung unserer APIs. Das „Ratenlimit“ besteht beispielsweise darin, die Anzahl der Aufrufe einer API in einem bestimmten Zeitintervall zu begrenzen.

Trotz der Implementierung dieses Schutzes war es uns wichtig, die Nutzungsgrenze unserer API und unserer Plattform abschätzen zu können. Mit der Ankunft neuer Kunden wird die Nutzung der API und damit die Belastungssteigerung progressiv sein.

Der Begriff „Charge Shot“ kann je nach Profil von Personen oder Unternehmen unterschiedlich definiert werden.

Für uns geht es beim Ausführen von Load Shots darum, in sehr kurzer Zeit eine große Anzahl von Aufrufen an unsere API zu simulieren, mit dem Ziel, „explodieren” unsere API.


Gatling: unser erster Belastungstest

Um diese Grenzen zu finden, wandten wir uns der Lösung zu Gatling. Warum nicht andere „schnellere“ Tools wie z arbeitenein Befehlszeilentool, das Entwicklungen nicht beeinflusst?

Bei RCA wird das Testökosystem mit der API aufgebaut Karateein automatisiertes Testtool, das darauf abzielt, einfach zu bedienen zu sein, egal ob Sie ein Entwickler oder eine weniger technisch versierte Person sind.

Mit der Sprache Gurke, können wir unsere Testszenarien schreiben. Zum Beispiel :

Feature: Guess the word   # The first example has two steps   Scenario: Maker starts a game      When the Maker starts a game      Then the Maker waits for a Breaker to join
Wechseln Sie in den VollbildmodusBeenden Sie den Vollbildmodus

Gatling kann diese Karate-Szenarien wiederverwenden, um Angriffsschüsse auszuführen. Die Integration in eine API ist sehr einfach. Holen Sie sich einfach die Abhängigkeit Karate-Gatling :

    com.intuit.karate    karate-gatling    test
Wechseln Sie in den VollbildmodusBeenden Sie den Vollbildmodus

Als wir diese Workaround-Lasttests initiierten, war nur DSL Scala verfĂĽgbar. Inzwischen wurde eine Java-DSL erstellt.

class GatlingSimulation extends Simulation{  val test = scenario("tirs-charge").exec(karateFeature("classpath:scenarios/charge/tirs-charge.feature"))
Wechseln Sie in den VollbildmodusBeenden Sie den Vollbildmodus

Nach dem Erstellen eines Profils Maven Der folgende Befehl ist diesen Belastungstests gewidmet und ermöglicht die Ausführung unserer Klasse Gatling-Simulation: mvn clean test-compile gatling:test

Gatling generiert dann einen HTML-Bericht mit vollständigen Informationen über die Anzahl der gesendeten Anfragen, durchschnittliche Antwortzeiten, Anfragestatus, wie in den folgenden Berichten gezeigt:

Rapport Gatling als nächstes

Auf der ersten Grafik sehen wir schnell, dass die Indikatoren auf den ersten Blick richtig erscheinen. Die API beantwortete die 3.000 Anfragen in maximal 800 Millisekunden. FĂĽr eine API und nach unserer Erfahrung ein durchaus angemessener Wert.

Dieser Trend wird im Balkendiagramm bestätigt. Unsere API hat innerhalb von 200 ms geantwortet.

Die in den Diagrammen sichtbaren Reaktionszeitbereiche (800 ms, 1200 ms) sind von Gatling definierte Basiswerte.


Integration | Automatisierung in CI/CD

Nachdem das Gatling-Szenario geschrieben wurde, ist es durchaus möglich, es zu testen, indem Sie es auf Ihrer eigenen Workstation ausführen. Ein Load-Shot auf einer API, die auf einem eigenen Computer bereitgestellt wird, ist es auch. Aber was bringt es, diesen Test lokal oder von Ihrer Workstation aus durchzuführen? Jeder Schuss hängt von der Leistung und Kapazität Ihres Computers zu diesem Zeitpunkt ab. Wenn es unser Ziel ist, Grenzen für unsere API zu finden, führt dies nicht zu einer relevanten Bilanz.

Um interpretierbare Ergebnisse zu erhalten, haben wir unsere API auf einer Infrastruktur bereitgestellt „testen“, fast gleichbedeutend mit dem der Produktion. Es ist leicht unterdimensioniert.

Wie bereits erwähnt, bestand unser Ziel darin, uns ein Aufforderungslimit zu geben, damit unsere API akzeptable Antwortzeiten hat. Die Infrastruktur, auf der die Karate-Szenarien laufen, musste daher leistungsfähig genug sein, was bei unseren Computern nicht der Fall ist.

Was bringt es, Tools wie Maven zu installieren, um einen Charge Shot ausführen zu können?

Die relativ einfach zu bedienende Benutzeroberfläche von GitLab ermöglicht es jedem Profil, Pipelines schnell auszulösen. Bei RCA, dem Mechanismus, der die Pipelines betreibt, GitLab-Runnerist auf einer leistungsfähigen Infrastruktur installiert.

Wir haben einen neuen Arbeitsplatz geschaffen“🧯Schüsse beim Testen laden 🔥“ in unserer bestehenden GitLab-Pipeline, um es zu ermöglichen, einen Ladevorgang auf unserer API auszuführen, die in der Produktions-ISO-Umgebung bereitgestellt wird.

Pipeline-GitLab-CI


Die aufgetretenen Probleme (und Lösungen)


Infrastruktur als Code

Der Aufruf unserer API erfolgt nach dem Abrufen eines Authentifizierungstokens über Gravitee. Wir hatten ein „Ratenlimit“ von 1000 Anrufen für einen Zeitraum von 10 Minuten festgelegt. Während unseres Ladevorgangs führten wir mehrere Zehntausend Anrufe in 1 Minute durch. Das „Ratenlimit“ ist logischerweise erreicht!

Trotz einer Modifikation der Testinfrastruktur zur Deaktivierung dieser „Ratenbegrenzung“ ist ein weiterer Knackpunkt aufgetreten.


Single anrufen

In unserem Karate-Szenario verursacht 1 Aufruf an die API 1 Aufruf an Gravitee. Für mehrere zehntausend Aufrufe haben wir also die gleiche Menge an Tokens erstellt. Unser Ladungsschuss soll jedoch nicht die Robustheit von Gravity testen. Zumal das Team, das diese Infrastruktur aufgebaut hat, für deren Leistungsfähigkeit gesorgt hatte.

Und aus anderer Sicht macht es keinen Sinn, so viele Token zu generieren, also könnten wir genauso gut nur einen für unsere Tests erstellen.

Dazu stellt die Karate-API eine Methode bereit AnrufSingle eine Ressource nur einmal aufzurufen, in unserem Fall die Generierung des Tokens.

var result = karate.callSingle('classpath:scenarios/api/authentification.feature', config);
Wechseln Sie in den VollbildmodusBeenden Sie den Vollbildmodus

Das Ergebnis der AusfĂĽhrung dieses Befehls kann in der folgenden generierten Tabelle auf der Ebene der rot eingekreisten Zeile ĂĽberprĂĽft werden: 1 einzelne AusfĂĽhrung auf der Ressource POST /Bearer/Token wurde produziert.

Statistik Gatling

Dies hat zur Folge, dass unser Charge Shot während der Gültigkeit des Tokens ausgeführt werden muss, unter Strafe der Generierung einer großen Anzahl von Fehlern 401 nicht Autorisiert.


Ergebnisanalyse

Um ein Limit für unsere API zu bestimmen, haben wir mehrere Laderunden durchgeführt. Beginnend mit einigen hundert Anrufen pro Minute haben wir die Anzahl der Anrufe schrittweise erhöht, die Ausführungszeit verkürzt, bis wir schlechtere Reaktionszeiten für die Lieferung an unsere Kunden hatten.

In den folgenden von Gatling generierten Diagrammen sind zwei Informationen verfĂĽgbar: die Anzahl der Anfragen und die Anzahl der Benutzer zu einem Zeitpunkt t.

Diese Daten sind stabil und zeigen, dass während des Brennens kein Klebepunkt auftritt. Die Anzahl der Anfragen ist stabil.

Gatling-Bericht – Diagramm zur Anzahl der Anfragen

Neben den Diagrammen bietet Gatling einen textuellen Report mit der Anzahl der Anfragen während des Schusses, der maximalen Antwortzeit sowie Statistiken zur Verteilung der Antwortzeiten.

Rapport Gatling - globale Informationen

Ein wichtiger repräsentativer Datenwert für den Zustand unserer API ist der CPU-Verbrauch. Diese Informationen sind in den bei RCA vorhandenen Grafana-Dashboards verfügbar, die es uns ermöglichen, unsere Interpretation der Ergebnisse von Gatling zu validieren.

Grafana-Vorstand

Wir sind gekommen, um ein Limit fĂĽr unsere API zu identifizieren. Eine Aufnahme, die 50.000 Benutzer ĂĽber 30 Sekunden simuliert, liefert uns akzeptable Reaktionszeiten, d. h. unter 800 ms.

Die von RCA erstellte kollaborative Plattform hat ein Produktionsvolumen von 12.000 bis 16.000 Benutzern pro Stunde. In dem Wissen, dass die Umgebung im Vergleich zur Produktion auĂźerdem unterdimensioniert ist, werden diese 50.000 Benutzer in 30 Sekunden in der Lage sein, unsere API weitgehend anzufordern.


Die Beiträge dieses Experiments

Die Integration von charge shots in unser Team war eine Entdeckung. Nachdem wir uns mit der Karate-API und der Gatling-Erweiterung auseinandergesetzt hatten, konnten wir schnell unsere ersten Ergebnisse verwerten und uns eine Größenordnung über die Aufrufkapazität unserer API geben.

Glücklicherweise wurden diese Tests durchgeführt, sie ermöglichten es uns, ein Leistungsproblem zu erkennen und zu beheben. Dies ist beruhigend für die weitere Entwicklung und schützt uns vor ähnlichen Problemen.

Lasttests im gesamten Team zu integrieren, ist eine gute Sache. Mit der Sensibilisierung und Automatisierung von Load Shots in GitLab CI kann jedes Personenprofil Load Shots ausfĂĽhren, das Diagramm abrufen und eine erste Interpretation davon vornehmen.

Sylvain Nagel (Cinch) / Jean-Philippe Baconnais (Zenika)

Finden Sie diesen Artikel auf der Sylvains Medium-Konto und innerhalb weniger Tage auf der RCA-Blog.

Leave a Reply

Your email address will not be published. Required fields are marked *

Most Popular

On Key

Related Posts