Sie möchten wissen, wie sich Ihre API bei genau 500 Anfragen pro Sekunde verhält, nicht „so schnell, wie N Threads sie belasten können“. Die meisten Lasttest-Tools legen die Gleichzeitigkeit fest und lassen die Anfragerate variabel. Vegeta macht das Gegenteil: Sie legen die Rate fest, und es sendet diese Anzahl von Anfragen pro Sekunde, unabhängig davon, wie der Server antwortet. Dieser Unterschied ist wichtig, wenn es Ihnen auf die Zahl ankommt, die im Antwortbogen steht: Durchsatz bei einer Ziellast und die Latenz, die Sie tatsächlich in einem SLO versprechen würden.
Was Vegeta ist
Vegeta ist ein HTTP-Lasttest-Tool für die Kommandozeile, geschrieben in Go. Es ist auch als Go-Bibliothek nutzbar, aber dieses Tutorial konzentriert sich auf die CLI. Die Kernidee ist eine konstante Anfragerate. Sie weisen Vegeta an, „100 Anfragen pro Sekunde für 30 Sekunden zu senden“, und es hält dieses Tempo, indem es bei Bedarf Worker hinzufügt. Wenn der Server langsamer wird, sendet Vegeta weiterhin planmäßig neue Anfragen, anstatt darauf zu warten, dass alte abgeschlossen werden.
Dieses Design bietet Ihnen einen Lasttest nach offenem Modell. Echter Traffic kommt nach seinem eigenen Takt an; Benutzer pausieren und warten nicht auf Ihren langsamen Endpunkt, bevor der nächste Benutzer erscheint. Ein raten-basiertes Tool entspricht diesem Verhalten.
Raten-basierte vs. Gleichzeitigkeits-basierte Last
Hier ist der Unterschied, der viele Leute verwirrt.
Ein Gleichzeitigkeits-basiertes Tool (ein fester Pool von Threads oder virtuellen Benutzern, die jeweils Anfrage-Antwort-Schleifen durchlaufen) verwendet ein geschlossenes Modell. Wenn der Server langsam wird, stockt die Schleife, sodass die tatsächliche Anfragerate sinkt. Sie haben Last angefordert, aber das Tool hat unauffällig zurückgefahren. Das verbirgt den Rückstau, den Sie in der Produktion sehen würden.
Ein raten-basiertes Tool wie Vegeta verwendet ein offenes Modell. Sie legen die Ankunftsrate fest. Wenn der Server nicht mithalten kann, stauen sich Anfragen, die Latenz steigt, und der Bericht zeigt dies. Sie erhalten ein ehrliches Bild davon, was passiert, wenn die Nachfrage die Kapazität übersteigt.
Keines der Modelle ist falsch. Verwenden Sie Gleichzeitigkeit, wenn Sie wissen möchten, „wie viele gleichzeitige Benutzer kann ich verwalten“. Verwenden Sie ein Ratenmodell, wenn Sie wissen möchten, „was passiert bei 2.000 Anfragen pro Sekunde“. Vegeta ist die zweite Art. Für eine breitere Übersicht über den Tooling-Bereich siehe die Top-API-Lasttest-Tools.
Vegeta installieren
Wählen Sie die Option, die zu Ihrer Einrichtung passt.
Homebrew unter macOS:
brew update && brew install vegeta
Andere Paketmanager:
# MacPorts
port install vegeta
# Arch Linux
pacman -S vegeta
# FreeBSD
pkg install vegeta
Aus dem Quellcode mit installiertem Go:
git clone https://github.com/tsenart/vegeta
cd vegeta
make vegeta
Sie können auch ein vorkompiliertes Binärpaket von der GitHub-Release-Seite herunterladen. Bestätigen Sie die Installation:
vegeta --help
Die Kernpipeline
Vegeta ist um Unix-Pipes herum aufgebaut. Ein Ziel wird eingegeben, ein Angriff wird ausgeführt, und ein Bericht wird ausgegeben. Der kleinste nützliche Durchlauf ist eine Zeile:
echo "GET http://localhost:8080/" | vegeta attack -duration=5s -rate=100 | vegeta report
Lesen Sie dies von links nach rechts:
echoschreibt ein Ziel (eine Methode und URL) in die Standardausgabe.vegeta attackliest dieses Ziel von der Standardeingabe und feuert 100 Anfragen pro Sekunde für 5 Sekunden ab. Das sind insgesamt 500 Anfragen.vegeta reportliest den binären Ergebnisstrom und gibt eine Zusammenfassung aus.
Das Flag -rate nimmt Anfragen pro Zeiteinheit entgegen. -rate=100 und -rate=100/1s bedeuten dasselbe. -rate=50/500ms bedeutet 50 Anfragen alle 500 Millisekunden. Das Setzen von -rate=0 entfernt die Begrenzung und sendet so schnell wie möglich, was ein völlig anderer Test ist.
Ein Textbericht sieht so aus:
Requests [total, rate, throughput] 500, 100.20, 100.18
Duration [total, attack, wait] 4.991s, 4.990s, 1.2ms
Latencies [min, mean, 50, 90, 95, 99, max] 412us, 1.3ms, 1.1ms, 1.9ms, 2.4ms, 5.1ms, 12ms
Bytes In [total, mean] 128500, 257.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:500
Error Set:
Lesen Sie zuerst die Latenzzeit-Zeile. Die Spalte 50 ist der Median. Die Spalte 99 ist der Tail (Ende der Verteilung): 1 Prozent der Anfragen waren langsamer als dieser Wert. Die "Tails" sind die Bereiche, in denen Benutzer Probleme spüren, daher ist ein gesunder Mittelwert mit einem schlechten 99. Perzentil immer noch ein Problem. Überprüfen Sie als Nächstes Success [ratio] und Status Codes. Eine Erfolgsquote von 100 Prozent mit ausschließlich 200er-Statuscodes bedeutet, dass der Server die Last bewältigt hat. Jegliche 5xx-Codes oder ein nicht leeres Error Set bedeuten, dass es angefangen hat zu versagen.
Ergebnisse speichern, dann vielseitig berichten
Direktes Pipelining an report ist für einen schnellen Überblick in Ordnung. Für alles, was Sie erneut prüfen möchten, speichern Sie die Rohdaten zuerst in einer Datei und generieren Sie dann jeden gewünschten Bericht aus dieser einen Datei.
echo "GET http://localhost:8080/" | \
vegeta attack -duration=10s -rate=200 -output=results.bin
Der Durchlauf ist nun in results.bin erfasst. Erstellen Sie einen Textbericht:
vegeta report results.bin
Erstellen Sie strukturiertes JSON für ein Dashboard oder einen Vergleich zwischen Durchläufen:
vegeta report -type=json results.bin > metrics.json
Erstellen Sie ein Latenz-Histogramm mit von Ihnen gewählten Intervallen:
vegeta report -type='hist[0,2ms,5ms,10ms,25ms,100ms]' results.bin
Das Histogramm zählt, wie viele Anfragen in jedes Latenzband fielen. Es ist eine schnelle Methode, um zu sehen, ob die Latenz eng gebündelt oder über einen weiten Bereich verteilt ist.
Das Targets-Dateiformat
Echte APIs benötigen mehr als nur GET-Anfragen. Verschieben Sie Ihre Ziele in eine Datei und übergeben Sie diese mit -targets. Das Standard-HTTP-Format ist zeilenbasiert und lesbar.
Erstellen Sie targets.txt:
GET http://localhost:8080/api/users
POST http://localhost:8080/api/users
Content-Type: application/json
@./payload.json
GET http://localhost:8080/api/users/42
Einige Regeln machen dies möglich:
- Die erste Zeile jedes Ziels ist
METHODE URL. - Header-Zeilen folgen direkt unter der Methoden-Zeile, ein
Schlüssel: Wertpro Zeile. - Eine Zeile, die mit
@beginnt, benennt eine Datei, deren Inhalt zum Anfragekörper wird. - Eine leere Zeile trennt ein Ziel vom nächsten.
- Zeilen, die mit
#beginnen, sind Kommentare.
Legen Sie Ihren JSON-Body in payload.json ab:
{ "name": "Ada", "role": "engineer" }
Führen Sie den Angriff gegen die Datei aus:
vegeta attack -targets=targets.txt -rate=50 -duration=30s | vegeta report
Vegeta durchläuft die Ziele der Reihe nach und wiederholt den Vorgang, bis die Dauer abläuft. Sie können auch globale Header in der Befehlszeile mit -header hinzufügen, was praktisch für die Authentifizierung ist:
vegeta attack -targets=targets.txt -rate=50 -duration=30s \
-header="Authorization: Bearer $TOKEN" | vegeta report
Für programmatische oder hochvolumige Durchläufe liest Vegeta auch ein JSON-Zielformat. Jede Zeile ist ein JSON-Objekt, und Sie wählen es mit -format=json aus:
{"method": "GET", "url": "http://localhost:8080/api/users"}
{"method": "POST", "url": "http://localhost:8080/api/users", "header": {"Content-Type": ["application/json"]}, "body": "eyJuYW1lIjoiQWRhIn0="}
Das Feld body ist base64-kodiert. Dieses Format lässt sich gut streamen, sodass Sie Ziele spontan generieren und mit -lazy direkt für Speichereffizienz einspeisen können.
Plots und Histogramme
Eine einzelne Zahl verbirgt Trends. Wenn die Latenz zur Hälfte eines Durchlaufs abnimmt, möchten Sie die Kurve sehen. Vegetas plot-Befehl wandelt einen Ergebnisstrom in eine interaktive HTML-Seite um:
vegeta attack -targets=targets.txt -rate=100 -duration=60s | \
vegeta plot > plot.html
Öffnen Sie plot.html in einem Browser. Sie erhalten ein Zeitreihen-Diagramm der Latenz über den gesamten Durchlauf, sodass ein langsamer Anstieg oder ein Spike während des Tests offensichtlich wird. Sie können mehrere Durchläufe zusammen plotten, um die Lastniveaus zu vergleichen:
vegeta attack -rate=50 -duration=30s -targets=targets.txt -output=50qps.bin
vegeta attack -rate=100 -duration=30s -targets=targets.txt -output=100qps.bin
vegeta plot 50qps.bin 100qps.bin > compare.html
Für Headless-Umgebungen überspringen Sie den Plot und exportieren stattdessen ein Histogramm oder die Roh-CSV-Daten mit encode:
vegeta encode -to=csv results.bin > results.csv
Wann Vegeta verwendet werden sollte
Greifen Sie zu Vegeta, wenn es um Rate und Kapazität geht:
- Sie benötigen Durchsatz und Latenz bei einer spezifischen Ziel-Anzahl von Anfragen pro Sekunde.
- Sie möchten die Rate finden, bei der die Latenz oder Fehlerrate zu steigen beginnt.
- Sie vergleichen zwei Builds oder zwei Infrastrukturkonfigurationen unter identischer, wiederholbarer Last.
- Sie möchten ein skriptfähiges Tool, das sich ohne GUI in eine Shell-Pipeline und einen CI-Job einfügen lässt.
Es ist ein fokussiertes Instrument. Es sendet HTTP-Anfragen mit einer bestimmten Rate und misst, wie der Server antwortet. Es skriptet keine mehrstufigen Benutzerpfade mit Verzweigungslogik und validiert keine Antwortkörper über Statuscodes hinaus. Dieser Fokus ist ein Feature; er hält das Tool klein und die Ergebnisse sauber.
Wenn Sie es mit anderen Testwerkzeugen vergleichen, decken die Vergleiche in k6 Lasttests und JMeter Lasttests die Alternativen des Gleichzeitigkeitsmodells ab. Für die grundlegenden Konzepte und Metriken ist das API-Performance-Test-Tutorial eine gute Einführung.
Wo funktionale Tests ins Spiel kommen
Lasttests beantworten die Frage „Ist es schnell genug?“. Sie beantworten nicht die Frage „Ist es korrekt?“. Ein Vegeta-Lauf kann 100 Prozent 200er-Statuscodes melden, während der Endpunkt den falschen Benutzer, einen veralteten Preis oder ein fehlerhaftes JSON-Feld zurückgibt. Jede dieser Antworten ist, aus Sicht eines Lasttest-Tools, eine schnelle, erfolgreiche 200er-Antwort.
Korrektheit erfordert eine andere Überprüfung: Zusicherungen auf den Antwortkörper, das Schema und die Geschäftsregeln. Das ist funktionale Testung, und sie gehört vor und neben Ihren Lasttests. Das sinnvolle Vorgehen ist, zuerst zu validieren, dass die API korrekt ist, und dann zu messen, wie sie unter einer bestimmten Rate funktioniert.
Hier ergänzt Apidog ein Tool wie Vegeta, anstatt mit ihm zu konkurrieren. In Apidog erstellen Sie Testszenarien mit visuellen Zusicherungen zu Status, Headern und JSON-Feldern, verketten Anfragen und steuern sie über Datendateien. Sie bestätigen, dass die API die korrekten Daten zurückgibt. Vegeta bestätigt dann, dass sie schnell bleibt, wenn dieser korrekte Pfad Hunderte Male pro Sekunde aufgerufen wird. Zwei Tools, zwei Fragen.
Apidog liefert auch eine Headless-CLI, sodass diese funktionalen Szenarien in derselben CI-Pipeline wie Ihr Lasttestschritt ausgeführt werden können. Installieren Sie es mit Node:
npm install -g apidog-cli
Führen Sie dann ein gespeichertes Szenario oder eine Suite anhand der ID aus, mit Reportern für Ihre Pipeline:
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Das Flag -t nimmt die Szenario-, Ordner- oder Suite-ID entgegen, -e die Umgebungs-ID und -r wählt einen oder mehrere Reporter (cli, html, json, junit). Die junit-Ausgabe passt in die meisten CI-Dashboards. Siehe das Apidog CLI Kommandozeilen-Tutorial für einen Schritt-für-Schritt-Durchlauf und den CI/CD Pipeline-Leitfaden für einen Copy-Paste-Workflow. Führen Sie zuerst den funktionalen Check aus und lassen Sie Vegeta dann die Endpunkte messen, die bestanden haben.
FAQ
Unterstützt Vegeta POST-Anfragen mit einem Body?
Ja. In der HTTP-Zieldatei platzieren Sie die Methode und URL in die erste Zeile, fügen einen Content-Type-Header hinzu und verweisen auf eine Body-Datei mit @./payload.json. Im JSON-Format setzen Sie die Felder method, url und ein base64-kodiertes body-Feld.
Was bewirkt -rate=0?
Es entfernt die Ratenbegrenzung und sendet Anfragen so schnell, wie es die Worker und Verbindungen zulassen. Das ist ein Maximaldurchsatztest, der sich von einem kontrollierten Test mit konstanter Rate unterscheidet. Für wiederholbare Kapazitätsmessungen legen Sie eine explizite Rate fest.
Wie lese ich die Latenz-Perzentile?
Die Latenzzeit-Zeile des Berichts zeigt Minimum, Mittelwert und die 50., 90., 95., 99. sowie maximale Perzentile. Konzentrieren Sie sich auf das 95. und 99. Perzentil. Sie beschreiben den langsamen Bereich, den echte Benutzer erleben, welcher allein durch den Mittelwert verborgen bleiben kann.
Kann Vegeta überprüfen, ob meine API korrekte Daten zurückgibt?
Nein. Es misst Durchsatz, Latenz und Statuscodes. Es macht keine Zusicherungen zu Antwortkörpern oder Schemata. Kombinieren Sie es mit einem funktionalen Testtool für die Korrektheit, und nutzen Sie Vegeta dann für Rate und Latenz.
Wie führe ich Vegeta in CI aus?
Es ist ein einzelnes Binärprogramm, das von stdin liest und Ergebnisse schreibt, sodass es in jeden Shell-Schritt integriert werden kann. Speichern Sie Ergebnisse mit -output und generieren Sie dann einen Text- oder JSON-Bericht als Build-Artefakt. Fügen Sie einen funktionalen Check, z.B. mit der Apidog CLI, vor dem Lastschritt hinzu, damit Sie nur Endpunkte messen, die ihre Zusicherungen bereits bestehen.
