Der seltsame Fall von Mr. Time To First Byte

14

Ich habe einen Webserver auf einem Linode 1024 VPS basierend

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6 (mit PHP-FPM, APC)
  • Lack 3.0.2

Und ein paar Blogs, die auf WordPress 3.3.1 basieren. Eines davon ist ein einfaches Blog mit der Standardkonfiguration, dem Standardthema und nur dem Post "Hello World", um den Server zu testen. Das andere ist ein von einem anderen Server geklontes Blog mit fast 10.000 Beiträgen und über 10.000 Kommentaren. Dieser Blog hat ungefähr 5.000 Unikate pro Tag.

Der Server gibt gute Zahlen für einen ab-Test für das Test-Blog an , aber der gleiche Test mit dem geklonten Blog ist unmöglich durchzuführen: Der ab-Test lädt den Server zu stark, und ich muss den Prozess anhalten, was trotzdem dazu führt, dass ab angezeigt wird Dieses wirklich schlechte Ergebnis .

Das htop zeigt im Normalbetrieb ebenfalls eine "normale" Belastung , während des ab-Tests jedoch eine normale hohe Belastung .

Es passiert noch etwas Merkwürdiges (das Wichtigste für mich): Die Zeit bis zum ersten Byte ist extrem hoch , aber danach wird die Seite sehr schnell geladen. Dies kann leicht mit Diensten wie tools.pingdom.com getestet werden, die dieses Ergebnis liefern . Bitte achten Sie auf den gelben Bereich, der "Wartezeit" bedeutet.

Warum passiert dies? Mögliche Ideen:

  • Ungültige PHP-FPM-Konfiguration
  • Die Antwortzeit von Linode DNS ist furchtbar. Unsinn - das Testblog löst DNS in Ordnung, TTFB ist fantastisch
  • Ungültige Nginx-Konfiguration

Falls jemand mehr Informationen benötigt,

Javipas
quelle
Ich denke, das kann etwas mit der if -fDirektive zu tun haben, die Sie in dem locationContainer in der Nginx-Konfiguration verwenden. Basierend auf dem, was ich hier lese wiki.nginx.org/Pitfalls , habe ich das Gefühl, dass -feine ineffiziente Suche nach der Datei durchgeführt wird, die ein Time To First Byte-Problem verursachen kann, insbesondere wenn Sie Verzeichnisse mit einer großen Anzahl von haben Dateien.
d34dh0r53
1
Ein paar Gedanken: a) Was sind die Unterschiede zum ursprünglichen Server, von dem das Blog geklont wurde (z. B. wird derselbe Stack ausgeführt?) B) Wenn möglich, führen Sie ab direkt vom Server aus, indem Sie localhost und den Port verwenden. Versuchen Sie, über Lack zuzugreifen, und greifen Sie dann direkt auf nginx zu. c) Aktivieren Sie langsame MySQL- und PHP-FPM-Protokolle. d) Führen Sie mysqltuner.pl aus und prüfen Sie, ob Sie Ihre MySQL-Leistung verbessern können (das wäre der offensichtlichste Unterschied zwischen den Blogs - oder Plugins). e) Die von Ihnen gepostete PHP-FPM-Konfiguration scheint nicht die von nginx verwendete zu sein (/var/run/php5-fpm-tpnet.sock! = /var/run/php5-fpm-www-data.sock)
Cyberx86
1
Auf jeden Fall ein PHP-Problem. Wordpress ist sehr langsam. Sie benötigen ein Caching-Plugin, um eine angemessene Ladezeit zu erhalten, wenn Sie so viel Inhalt haben.
Martin Fjordvald
2
Sie sagten, Sie können ab auf localhost ausführen und 4k req / s erhalten. Auf welchen localhost (vorherige / aktuelle) beziehen Sie sich? Wenn dieser Wert von Ihrem aktuellen Server stammt - dem mit dem hohen TTFB -, ist Ihr Problem jetzt viel interessanter, da Sie PHP, MySQL und Ihren Webserver effektiv eliminiert haben. TTFB enthält DNS, Roundtrip-Zeit und Verarbeitungszeit. Ein langer TTFB ist normalerweise auf die Verarbeitung zurückzuführen (z. B. PHP / MySQL). Der Punkt, ab direkt gegen Nginx zu laufen, ist, die anderen Komponenten zu eliminieren. Außerdem sollte Varnish, wenn das Setup richtig ist, das Backend umgehen und sehr hohe Anforderungen stellen.
cyberx86
1
Ihre localhost-Tests scheinen ungültig zu sein - Sie haben Ihr Blog nicht abgerufen. Beachten Sie den Unterschied in der Seitengröße: 7500 Bytes beim Zugriff von der Domäne, 151 Bytes von localhost. Da Sie wahrscheinlich mehrere virtuelle Hosts haben, müssen Sie den Host-Header an ab übergeben. ab -n 1000 -c 100 -H 'Host: mysite.com' http://127.0.0.1/Das heißt - der Unterschied zwischen zwischengespeicherten (Lack) und nicht zwischengespeicherten Ergebnissen reicht aus, um die Position zu bestätigen, dass das Problem nicht mit dem Netzwerk, DNS usw. zusammenhängt und wie erwartet in der Verarbeitung liegt.
Cyberx86

Antworten:

24

Erstens ist dies keine Antwort, sondern vielmehr ein diagnostischer Ansatz.

Dies ist keineswegs umfassend - oder auch nur etwas Nahes, es ist nur ein Ausgangspunkt.

Zeit bis zum ersten Byte

Das Time-to-First-Byte (TTFB) besteht aus einer Reihe von Komponenten:

  • DNS-Suche: Ermitteln der IP-Adresse der Domain (mögliche Verbesserung: mehr / verteilte / reaktionsfähige DNS-Server)
  • Verbindungszeit: Öffnen Sie einen Socket zum Server, verhandeln Sie die Verbindung (ein typischer Wert sollte in der Nähe der Ping-Zeit liegen - ein Roundtrip ist normalerweise erforderlich - Keepalive sollte für spätere Anfragen hilfreich sein).
  • Warten: Erstes Verarbeiten erforderlich, bevor das erste Byte gesendet werden kann (hier sollte Ihre Verbesserung liegen - dies ist für dynamischen Inhalt am wichtigsten.

Wenn Sie sich eine ApacheBench-Ausgabe ansehen, sehen Sie auch:

  • Verarbeitung: Dies ist die Summe aus Warten + vollständiger Übertragung von Inhalten (wenn die Übertragungszeit erheblich länger ist als erwartet, um die empfangene Datenmenge herunterzuladen, erfolgt eine weitere Verarbeitung (nach dem ersten empfangenen Byte) (z. B. die Seite) Inhalt wird gelöscht, sobald er verfügbar ist.)

Vergleiche zu Eliminate-Komponenten

Mit wenigen Ausnahmen liegt Ihr Problem in der Backend-Verarbeitung, die normalerweise auf zu komplexen / ineffizienten Code oder schlecht konfiguriertes MySQL zurückzuführen ist.

Eine gute Möglichkeit, dieses Problem zu lösen, besteht in einer Reihe von Vergleichen, durch die verschiedene Aspekte Ihres Setups beseitigt werden. Ein guter Vergleich sollte so konstant wie möglich sein, um das Problem einzugrenzen. Derzeit haben Sie die folgenden Vergleiche bereitgestellt:

  1. Identische (geklonte) Site auf altem und neuem Server:
    • Unterschied: Server
    • Ergebnis: Alter Server ist schnell; Neuer Server ist langsam
    • Anmerkungen: Hier müssen Sie die Unterschiede zwischen diesen Servern quantifizieren - sowohl hinsichtlich des verwendeten Stacks (Nginx usw.) als auch der Hardware (ist der alte Server schneller, weil er leistungsstärker ist?).
    • Fazit: Der Code kann bei der richtigen Einrichtung möglicherweise schnell ausgeführt werden
  2. Test-Site mit vollständiger Site auf dem neuen Server
    • Unterschied: Inhalt, Themen, Plugins usw
    • Ergebnis: Die Testseite ist schnell, die vollständige Seite ist langsam
    • Anmerkungen: Theoretisch sollte dieser Test Ihnen helfen, viele Aspekte Ihres Setups zu eliminieren - DNS, Netzwerk, sogar Ihr Nginx / PHP / MySQL-Setup - es ist jedoch nicht ganz "fair".
    • Fazit: Der zusätzliche Inhalt hat einen erheblichen Einfluss auf die Leistung

Im Idealfall müssen Sie Ihre gesamte Website duplizieren und dann den gesamten Inhalt mit Ausnahme eines Artikels und der zugehörigen Kommentare löschen. Der Sinn dieses Tests wäre, abschließend festzustellen, ob die große Menge an Inhalten das Problem ist oder ob andere Aspekte Ihres Setups (WordPress-Plugins, Theme usw.) die Ursache sind. Sie würden im Wesentlichen die Leistung identischer Websites auf demselben (neuen) Server vergleichen - also dieselbe Seite (dieselbe Länge usw.) laden - mit dem einzigen Unterschied, dass der gesamte Websiteinhalt (z. B. besteht eine gute Chance, dass einige Plugins dies nicht tun) gut skalieren mit erhöhtem Inhalt).

Ohne etwas zu ändern, gibt es einige andere Vergleiche, die Sie durchführen können:

  • Testen Sie von einem entfernten Standort aus im Vergleich zu einem lokalen Standort. Auf diese Weise können Sie feststellen, ob Netzwerk, Latenz, DNS usw. die Ursache sind
    • Sie haben dies bereits (etwas) getan und sind meistens zu dem Schluss gekommen, dass Sie kein Netzwerkproblem haben.
  • Test über Varnish (dh Port 80) gegen Nginx direkt (Port 8080) - versuchen Sie, Ihre Konfiguration zwischen den Tests nicht zu ändern - verwenden Sie einfach den richtigen Port. Dies zeigt Ihnen die Wirkung von Lack. Da es sich bei Varnish um eine Caching-Ebene handelt, sollten alle Anforderungen nach der ersten sehr schnell verarbeitet werden. Im Wesentlichen sollten das Back-End und die zum Generieren einer dynamischen Seite erforderliche Verarbeitung umgangen und die zwischengespeicherte Kopie sehr schnell bereitgestellt werden.
    • Sie haben dies getan (allerdings nicht vor Ort) und gezeigt, dass Lack einen signifikanten positiven Einfluss auf Ihre Leistung hat.

Optimieren Sie Ihr Backend

Zu diesem Zeitpunkt sollten Sie entweder das Problem gefunden oder die Schlussfolgerung gezogen haben, dass es in Ihrem Backend liegt. Das lässt Sie Nginx, PHP oder MySQL.

(Ich soll hier erwähnen, dass es immer praktisch ist , zu wissen , ob Ihre Engpass CPU, RAM oder I / O - zwischen sar, top, iostat, vmstat, free., Etc. sollten Sie in der Lage sein , bis zu einem gewissen Abschluss dazu kommen)

Nginx

Nginx nimmt nur Anforderungen entgegen und stellt entweder statischen Inhalt bereit oder verschiebt die Anforderungen nach PHP-FPM. In der Regel gibt es mit Nginx nicht viel zu optimieren.

  • Setzen Sie Arbeiter = # CPU-Kerne
  • Keepalive aktivieren (ein Wert von 10-15 ist gut)
  • Deaktivieren Sie die nicht benötigte Protokollierung
  • Erhöhen Sie bei Bedarf die Puffergröße
  • Vermeiden Sie if-Anweisungen (verwenden Sie statische Namen anstelle von regulären Ausdrücken, wenn möglich, beseitigen Sie nicht benötigte Erweiterungen)

Idealerweise haben Ihr Testblog und Ihr geklontes Blog identische Konfigurationen. In diesem Fall haben Sie Nginx effektiv als Problem beseitigt.

Anwendung

Wenn Sie versuchen, ein Problem in Ihrem Code zu identifizieren (z. B. ein langsames Plugin usw.), sind die langsamen Protokolle der Ausgangspunkt.

  • Aktivieren Sie das langsame MySQL-Protokoll und das langsame PHP-FPM-Protokoll. Führen Sie Ihren Benchmark aus und sehen Sie, was als langsam herauskommt.

MySQL

PHP

  • nicht benötigte Erweiterungen deaktivieren,
  • deaktiviere register_globals, magic_quotes_ *, expose_php, register_argc_argv, always_populate_raw_post_data
  • Erhöhen Sie das memory_limit
  • open_basedir und safe_mode haben erhebliche Auswirkungen auf die Leistung, können aber auch eine zusätzliche Verteidigungsebene darstellen. Testen Sie mit und ohne sie, um festzustellen, ob ihre Auswirkungen auf die Leistung tolerierbar sind.

PHP-FPM

  • Passen Sie die pm * -Werte an - erhöhen Sie sie, um mit hoher Last fertig zu werden

Es ist erwähnenswert, dass Ihre htop-Ergebnisse zeigen, dass PHP-Fpm den Großteil der CPU beansprucht - und Ihr Problem scheint direkt damit in Zusammenhang zu stehen.

Caching

Sobald Sie jeden wahrscheinlichen Engpass optimiert haben, können Sie mit dem Caching beginnen.

  • Sie haben bereits einen opCode-Cache (APC) - stellen Sie sicher, dass dieser funktioniert (es liegt eine Testdatei bei) - überprüfen Sie Ihre Cachetrefferquote und speichern Sie den APC-Cache nach Möglichkeit nicht auf der Festplatte, sondern im Arbeitsspeicher.
  • Richten Sie Ihren Code für den Cache ein (z. B. mit einem Plugin für Wordpress wie W3TC)
  • Mit Nginx können Sie FastCGI-Caching einrichten. Da Sie jedoch über Varnish verfügen, ist dies am besten zu vermeiden.
  • Richten Sie eine Caching-Ebene ein, z. B. "Lack" (was Sie bereits getan haben), und vergewissern Sie sich, dass dieser funktioniert (verwenden Sie z. B. "Lackstat", lesen Sie " Erreichen einer hohen Hitrate" ).
  • Fügen Sie mehr Caching für Komponenten Ihrer Site hinzu - z. B. MemCached, falls zutreffend

Angesichts der Einschränkungen Ihrer Anwendung und Hardware können Sie die Back-End-Leistung unter Umständen nicht so stark verbessern, um die Verwendung des Back-End zu minimieren.

Weitere Lektüre

cyberx86
quelle
2
Das ist eine fantastische Zusammenfassung der zu analysierenden Punkte. Vielen Dank für den Kommentar. Ich werde versuchen, mit all diesen Vorschlägen einen intensiven Test durchzuführen - einige davon sind, wie Sie sagten, bereits klar - und sehen, ob ich das Problem endlich erkennen kann. Viele Grüße, cyberx86.
Javipas
Über die memory_limitwurde in einem anderen Beitrag darauf hingewiesen, dass es bei der Leistung nicht hilft.
Forloop