Zum Inhalt springen
EuroVPSEuroVPS

Server oder Anwendung? So messen Sie den Engpass

Die Zeit bis zum ersten Byte an jedem Hop, Reservezähler auf der Maschine und ein nach blockierendem Frame gruppiertes Slow Log verorten eine langsame Website in einer Schicht, bevor irgendetwas geändert wird.

Von EuroVPS EngineeringDer Maschinenraum

7 Min. Lesezeit
In diesem Artikel 7 Abschnitte
Kurz gesagt
  • Messen Sie die Zeit bis zum ersten Byte an jedem Hop: durch den Edge, direkt am Origin und auf localhost. Die größte Lücke zwischen zwei benachbarten Werten ist die Schicht, der die Latenz gehört.
  • Lesen Sie die Reserve der Maschine, solange sie langsam ist: CPU idle und steal, verfügbarer Speicher, await der Platten und Warteschlangentiefe. Überall Reserve unter einer langsamen Website heißt, die Begrenzung sitzt oberhalb der Hardware.
  • Innerhalb der Anwendungsschicht gruppieren Sie: Anfragen nach URL, langsame Anfragen nach ihrem blockierenden Frame, Queries nach Digest. Jedes davon verdichtet Tausende Zeilen zu einer kurzen Rangliste mit ein oder zwei Namen an der Spitze.

Zeit bis zum ersten Byte an jedem Hop

Theorien über eine langsame Website entstehen leicht und lassen sich schwer abschließen. Drei Messungen schließen sie ab. Nehmen Sie die Zeit bis zum ersten Byte durch den öffentlichen Edge, noch einmal direkt gegen den Origin unter Umgehung des Edge, und noch einmal auf dem Anwendungshost gegen localhost. Die Differenz zwischen zwei benachbarten Messwerten ist der Preis dieser Schicht.

TERMINAL
# through the edge
curl -s -o /dev/null -w 'dns=%{time_namelookup} tls=%{time_appconnect} ttfb=%{time_starttransfer}\n' https://site.example/

# direct to the origin, edge bypassed
curl -s -o /dev/null -w 'ttfb=%{time_starttransfer}\n' --resolve site.example:443:ORIGIN_IP https://site.example/

# on the host, nothing in front of the application
curl -s -o /dev/null -w 'ttfb=%{time_starttransfer}\n' http://127.0.0.1/

Was auf localhost übrig bleibt, ist die Anwendung und die Dienste, die sie aufruft. Die Schicht mit der größten Lücke ist die, in die der Rest der Arbeit geht.

Reserve, solange es wehtut

Lesen Sie die Zähler während der langsamen Phase, nicht danach.

TERMINAL
vmstat 1 5        # r (run queue), wa (I/O wait), st (steal), id (idle)
iostat -x 1 5     # await and aqu-sz per device
free -m           # the available column, not used

Eine lange Run Queue bei niedrigem idle ist eine CPU-gebundene Maschine. Hohes I/O wait mit hohem await auf dem Gerät ist Storage. Steal ist ein Nachbar auf einem geteilten Hypervisor, der Zyklen nimmt, die der Gast wollte. Untätige CPU, verfügbarer Speicher und Geräte mit niedrigem await unter einer langsamen Website bedeuten, dass die Maschine auf etwas wartet, das ihr nicht gehört: einen externen Aufruf, einen Lock, ein Query, das aus anderen Gründen als der Hardware langsam ist. Mehr Hardware an diesem Punkt erzeugt eine noch untätigere Maschine, die immer noch langsam ist.

Es gibt eine dritte Kategorie zwischen den beiden, und sie ist häufig: der Pool. Die Statusseite von PHP-FPM zeigt eine Listen Queue. Eine Warteschlange wartender Anfragen bei untätiger CPU bedeutet, dass jeder Worker belegt ist, meist blockiert im selben langsamen Aufruf, und die Website ist langsam wegen einer Konfigurationsgrenze, nicht wegen einer Ressourcengrenze. Dieselbe Form zeigt sich als gesättigter Datenbank-Connection-Pool oder als volle Backend-Queue in HAProxy. Die Maschine ist unschuldig, und der Code ist noch nicht verurteilt. Die Poolgröße und der Aufruf, auf den gewartet wird, sind die nächsten beiden Messwerte.

Lesen Sie den Traffic vor dem Code

Das Access Log sagt, welche Art von Problem das ist. Finden Sie zuerst das Log pro vhost. Das Standard-Log kann einen kleinen Bruchteil des echten Traffics enthalten, und eine Zählung über die falsche Datei liefert eine selbstbewusste falsche Antwort.

TERMINAL
tail -n 100000 access.log | awk -F'"' '{print $2}' | sort | uniq -c | sort -rn | head

Wenige URLs, tausendfach wiederholt, sind die Website, die sich selbst aufruft, und die Lösung ist ein Cache vor diesen URLs. Anfragen, die in Sitemap-Reihenfolge marschieren, sind ein Crawler, und die Lösung ist ein Rate Limit. Ein breiter, gleichmäßiger Anstieg über viele URLs ist Nachfrage, und die Lösung ist Kapazität.

Verdichten Sie das Slow Log und das Query Log

Ein Slow Log ist ein Haufen Stack Traces, bis es gruppiert wird. Aktivieren Sie das Slow Log von PHP-FPM mit einem Schwellenwert, der die Anfragen erfasst, über die sich Nutzer beschweren, dann gruppieren Sie jeden Trace nach dem Frame, in dem er blockiert war, dem Blatt, und zählen Sie. Die Rangliste ist kurz, und ganz oben steht meist ein externer Aufruf oder ein Query.

Auf der Datenbankseite ordnen Sie nach Digest, nicht nach Plan. Uneinheitliche Parametrisierung zerlegt ein logisches Query in viele Pläne, die einzeln harmlos aussehen. Nach Digest summiert, setzt sich der wahre Eigentümer der Datenbankzeit wieder zu einer Zeile zusammen.

TERMINAL
-- MySQL and Percona: by statement digest
SELECT digest_text, count_star, sum_timer_wait
FROM performance_schema.events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC
LIMIT 10;

-- SQL Server: by query hash
SELECT query_hash, COUNT(*) AS plans, SUM(total_worker_time) AS cpu
FROM sys.dm_exec_query_stats
GROUP BY query_hash
ORDER BY cpu DESC;

Bevor irgendein Index geschrieben wird, prüfen Sie die tatsächliche Zeilenzahl und die Indizes, die bereits existieren. Ein Index auf einer Tabelle, die keinen braucht, ist ein langsamerer Schreibpfad.

Lesen Sie die Primärquelle, nicht eine plausible Geschichte

Die GeschichteDie Quelle, die sie klärt
Er ist abgestürzt, der Speicher war volldmesg, journalctl --list-boots, last -x reboot: hat er neu gestartet, und warum
Die Datenbank ist korruptdas eigene Error Log der Datenbank, mit grep nach Crash- und Corruption-Meldungen
Ein außer Kontrolle geratener Prozess frisst die CPUps --forest und /proc/<pid>/cmdline: seine wahre Identität und sein Elternprozess, nicht ein plausibler Name
Wir sehen Integritätsfehlerethtool -S auf dem Interface: null Leitungsfehler heißt, das Problem liegt oberhalb der Leitung
SELinux blockiert esausearch -m avc -ts recent per Pipe an audit2why: die Verweigerung, benannt, mit dem Policy-Modul, das sie behebt

Jede Zeile ersetzt eine Theorie durch einen Messwert. Die letzte zählt auf einem System im Enforcing-Modus: Das Audit-Log beantwortet die Frage, ohne dass die Sicherheitshaltung geändert werden muss, um sie zu stellen.

Beweisen Sie es, dann verifizieren Sie mit derselben Messung

Korrelation liefert einen Verdächtigen. Eine kleine, umkehrbare Störung überführt ihn: Stoppen Sie die verdächtigen Queries für ein paar Sekunden und beobachten Sie, ob die Last wieder auffüllt. Füllt sie sofort wieder auf, ist der Live-Traffic der Treiber, und die Lösung gehört an den Edge, vor die Anfragen, die die Datenbank gar nicht erreichen sollten. Bis die Ursache bekannt ist, ist das System read-only. Wenn die Korrektur eingebaut ist, wird sie mit der Messung verifiziert, die das Problem gefunden hat: Hat die Zeit bis zum ersten Byte pro Hop es lokalisiert, bestätigt die Zeit bis zum ersten Byte pro Hop, dass es weg ist.

Was wir beheben und was wir zurückgeben

Am Edge, am selben TagIn Ihrem Code, mit der genauen Änderung
Micro-Caching mit Request Collapsing vor den heißen URLsDen synchronen Drittanbieter-Aufruf in einen Hintergrundjob mit Timeout und Fallback verlegen
Worker- und Buffer-Pools auf die gemessene Last dimensioniertDie Render-Schleife oder die Retry-Schleife entfernen
Ein Covering Index, online hinzugefügtDie Anwendungsdaten verfallen lassen, die unbegrenzt wachsen
Abgestimmte Retries und Timeouts in HAProxy, ein korrigierter SELinux-KontextPayload und Skripte kürzen, die an den Browser gehen

Wir ändern Ihren Code nicht. Wir benennen die Zeile, zeigen die Messung, die auf sie weist, und halten die Website am Laufen, während Sie sie beheben.

Klare Antworten

Woher weiß ich, ob mein Server oder meine Anwendung langsam ist?+

Lesen Sie die Reserve während der langsamen Phase: CPU idle und steal, verfügbarer Speicher, await der Platten. Haben alle drei Luft, liegt die Begrenzung oberhalb der Hardware, in der Anwendung oder in einem Dienst, den sie aufruft. Die Zeit bis zum ersten Byte auf localhost im Vergleich zum Edge bestätigt, welche Schicht.

Wie finden Sie ein langsames Datenbank-Query?+

Wir ordnen nach Digest, nicht nach Plan Handle, damit ein logisches Query mit vielen Parametrisierungen seine Gesamtkosten in einer Zeile zeigt. Dann prüfen wir Zeilenzahlen und vorhandene Indizes, bevor irgendein DDL geschrieben wird.

Können Sie einen Bot von einer echten Traffic-Spitze unterscheiden?+

Aus dem Access Log, über die Häufigkeit der URLs. Eine Handvoll URLs, tausendfach wiederholt, ist die Website, die sich selbst aufruft, Sitemap-Reihenfolge ist ein Crawler, ein breiter Anstieg ist Nachfrage. Jedes bekommt eine andere Lösung.

Ändern Sie meinen Code?+

Nein. Alles auf der Infrastrukturseite beheben wir am Edge am selben Tag, umkehrbar. Alles in Ihrem Code geben wir als die genaue Änderung zurück, mit der Messung, die sie begründet.

Ihre Website ist langsam, und niemand ist sich einig, warum.

Sprechen Sie mit einem Ingenieur, der jeden Hop misst, bevor er irgendetwas anfasst.

Mit einem Ingenieur sprechen

Sie haben das Ende erreicht.

Setzen Sie das Gelesene um

Was betreiben Sie?

Erzählen Sie uns von Workload, Traffic und Anforderungen an die Wiederherstellung. Beginnen Sie mit dem Server-Konfigurator oder besprechen Sie die Details mit einem Ingenieur.

Geschrieben von den Ingenieuren, die die beschriebene Infrastruktur bauen und betreiben.
Mit einem Ingenieur sprechen
XIn

Noch 7 Min.