Heim >Backend-Entwicklung >PHP-Tutorial >Nginx-Funktionsprinzip, Optimierung und Schwachstellen.

Nginx-Funktionsprinzip, Optimierung und Schwachstellen.

WBOY
WBOYOriginal
2016-08-08 09:32:37947Durchsuche


1. Nginx-Module und Arbeitsprinzipien

Nginx besteht aus Kernel und Modulen des Kernels Es ist sehr klein und prägnant, und die geleistete Arbeit ist auch sehr einfach. Es ordnet die Clientanforderung nur einem Standortblock zu, indem die Konfigurationsdatei nachgeschlagen wird (Standort ist eine Anweisung in der Nginx-Konfiguration, die für den URL-Abgleich verwendet wird). , und die Konfiguration an diesem Ort Jeder Befehl startet verschiedene Module, um die entsprechende Arbeit abzuschließen.

Nginx-Module sind strukturell in Kernmodule, Basismodule und Drittanbietermodule unterteilt:

Kernmodule: HTTP-Modul, EVENT-Modul und MAIL-Modul

Grundmodule: HTTP-Zugriffsmodul, HTTP-FastCGI-Modul, HTTP-Proxy-Modul und HTTP-Rewrite-Modul,

Module von Drittanbietern: HTTP-Upstream-Request-Hash-Modul, Hinweismodul und HTTP-Zugriffsschlüsselmodul.

Module, die von Benutzern nach ihren eigenen Bedürfnissen entwickelt werden, sind Module von Drittanbietern. Gerade durch die Unterstützung so vieler Module sind die Funktionen von Nginx so leistungsstark.

Nginx-Module sind funktional in die folgenden drei Kategorien unterteilt.

Handler (Prozessormodule). Dieser Modultyp verarbeitet Anforderungen direkt und führt Vorgänge wie die Ausgabe von Inhalten und die Änderung von Header-Informationen aus. Im Allgemeinen kann es nur ein Handler-Prozessormodul geben.

Filter (Filtermodul). Dieser Modultyp ändert hauptsächlich den von anderen Prozessormodulen ausgegebenen Inhalt und wird schließlich von Nginx ausgegeben.

Proxies (Proxy-Klassenmodul). Solche Module sind Module wie der HTTP-Upstream von Nginx. Diese Module interagieren hauptsächlich mit einigen Back-End-Diensten wie FastCGI, um Funktionen wie Dienst-Proxy und Lastausgleich zu implementieren.

Abbildung 1-1 zeigt den normalen HTTP-Anfrage- und Antwortprozess des Nginx-Moduls. Abbildung 1-1 zeigt den normalen HTTP-Anfrage- und Antwortprozess des Nginx-Moduls.

Nginx selbst leistet eigentlich nur sehr wenig Arbeit. Wenn es eine HTTP-Anfrage empfängt, ordnet es die Anfrage lediglich einem Standortblock zu, indem es die Konfigurationsdatei nachschlägt, und die Konfiguration an diesem Standort wird gestartet Verschiedene Module vervollständigen die Arbeit, sodass die Module als die eigentlichen Arbeitskräfte von Nginx angesehen werden können. Normalerweise umfassen Anweisungen an einem Standort ein Handlermodul und mehrere Filtermodule (natürlich können mehrere Standorte dasselbe Modul wiederverwenden). Das Handler-Modul ist für die Verarbeitung von Anfragen und den Abschluss der Generierung von Antwortinhalten verantwortlich, während das Filtermodul den Antwortinhalt verarbeitet.

Nginx-Module werden direkt in Nginx kompiliert, es handelt sich also um eine statische Kompilierungsmethode. Nach dem Start von Nginx wird das Nginx-Modul automatisch geladen. Im Gegensatz zu Apache wird das Modul zunächst in eine SO-Datei kompiliert und dann in der Konfigurationsdatei angegeben, ob es geladen werden soll. Beim Parsen der Konfigurationsdatei kann jedes Modul von Nginx eine bestimmte Anforderung verarbeiten, aber dieselbe Verarbeitungsanforderung kann nur von einem Modul abgeschlossen werden.

In Bezug auf den Arbeitsmodus ist Nginx in zwei Modi unterteilt: Single-Worker-Prozess und Multi-Worker-Prozess. Im Single-Worker-Prozessmodus gibt es zusätzlich zum Hauptprozess auch einen Single-Threaded-Worker-Prozess. Im Multi-Worker-Prozessmodus enthält jeder Worker-Prozess mehrere Threads. Nginx verwendet standardmäßig den Einzelarbeitsprozessmodus.

2. Nginx+FastCGI-Funktionsprinzip

1. Was ist FastCGI? >FastCGI ist eine skalierbare Hochgeschwindigkeitsschnittstelle für die Kommunikation zwischen HTTP-Servern und dynamischen Skriptsprachen. Die meisten gängigen HTTP-Server unterstützen FastCGI, einschließlich Apache, Nginx, lighttpd usw. Gleichzeitig wird FastCGI auch von vielen Skriptsprachen unterstützt, darunter PHP.

FastCGI wurde aus CGI entwickelt und verbessert. Der Hauptnachteil der herkömmlichen CGI-Schnittstellenmethode ist die schlechte Leistung, da der Skriptparser jedes Mal, wenn der HTTP-Server auf ein dynamisches Programm trifft, neu gestartet werden muss, um die Analyse durchzuführen, und die Ergebnisse dann an den HTTP-Server zurückgegeben werden. Dies ist bei hohem gleichzeitigem Zugriff nahezu unbrauchbar. Darüber hinaus weist die traditionelle CGI-Schnittstellenmethode eine geringe Sicherheit auf und wird heutzutage nur noch selten verwendet.

Der FastCGI-Schnittstellenmodus verwendet eine C/S-Struktur, die den HTTP-Server und den Skript-Parsing-Server trennen und einen oder mehrere Skript-Parsing-Daemons auf dem Skript-Parsing-Server starten kann. Jedes Mal, wenn der HTTP-Server auf ein dynamisches Programm trifft, kann es zur Ausführung direkt an den FastCGI-Prozess übermittelt und das Ergebnis dann an den Browser zurückgegeben werden. Mit dieser Methode kann der HTTP-Server ausschließlich statische Anforderungen verarbeiten oder die Ergebnisse des dynamischen Skriptservers an den Client zurückgeben, was die Leistung des gesamten Anwendungssystems erheblich verbessert.

2. Nginx+FastCGI-Funktionsprinzip

Nginx unterstützt keinen direkten Aufruf oder Parsing externer Programme (einschließlich PHP) muss die FastCGI-Schnittstelle passieren. Anruf. Die FastCGI-Schnittstelle ist ein Socket unter Linux (dieser Socket kann ein Datei-Socket oder ein IP-Socket sein).

Wrapper: Um ein CGI-Programm aufzurufen, wird auch ein FastCGI-Wrapper benötigt (unter einem Wrapper kann ein Programm verstanden werden, mit dem ein anderes Programm gestartet wird, z. B. ein Port oder eine Datei). Buchse. Wenn Nginx eine CGI-Anfrage an diesen Socket sendet, empfängt der Wrapper die Anfrage über die FastCGI-Schnittstelle und leitet dann einen neuen Thread ab. Dieser Thread ruft den Interpreter oder das externe Programm auf, um das Skript zu verarbeiten und die Rückgabedaten zu lesen. Der Wrapper leitet dann die zurückgegebenen Daten über die FastCGI-Schnittstelle an Nginx weiter und schließlich sendet Nginx die zurückgegebenen Daten (HTML-Seite oder Bild) an den Client. Dies ist der gesamte Betriebsprozess von Nginx + FastCGI, wie in Abbildung 1-3 dargestellt. Also brauchen wir zuerst einen Wrapper, die Arbeit, die dieser Wrapper erledigen muss:

Kommunizieren Sie mit Ningx über Sockets, indem Sie die Funktionen von fastcgi (Bibliothek) aufrufen (Lesen und Schreiben von Sockets sind Funktionen, die intern von implementiert werden fastcgi und sind für den Wrapper nicht transparent. fcgi und PHP-FPM FastCGI Die Schnittstellenmethode startet einen oder mehrere Daemon-Prozesse auf dem Skript-Parsing-Server, um dynamische Skripte zu analysieren. Diese Prozesse sind der FastCGI-Prozessmanager oder die FastCGI-Engine. spawn-fcgi und PHP-FPM sind zwei FastCGI-Prozessmanager, die PHP unterstützen. Dadurch ist HTTPServer vollständig entlastet und kann besser reagieren und Parallelität besser handhaben.

Ähnlichkeiten und Unterschiede zwischen spawn-fcgi und PHP-FPM:

1) spawn-fcgi ist Teil des HTTP-Servers lighttpd. Es ist ein eigenständiges Projekt geworden und wird allgemein verwendet in Verbindung mit lighttpd wird PHP unterstützt. Allerdings kann spwan-fcgi von ligttpd Speicherverluste verursachen oder FastCGI bei hohem gleichzeitigem Zugriff sogar automatisch neu starten. Das heißt: Der PHP-Skriptprozessor stürzt ab. Wenn der Benutzer zu diesem Zeitpunkt darauf zugreift, wird möglicherweise eine weiße Seite angezeigt (d. h. PHP kann nicht analysiert werden oder es tritt ein Fehler auf). 2) Nginx ist ein leichtgewichtiger HTTP-Server. Er muss einen FastCGI-Prozessor eines Drittanbieters verwenden, um PHP zu analysieren. Daher scheint Nginx sehr flexibel zu sein und von jedem Drittanbieter bereitgestellt werden zu können Der Parsing-Prozessor implementiert Verbindungen zum Parsen von PHP (einfach in nginx.conf einzurichten). nginx kann auch spwan-fcgi verwenden (lighttpd muss zusammen installiert werden, aber der Port muss für nginx vermieden werden. Einige ältere Blogs haben diesbezügliche Installations-Tutorials, da spawn-fcgi jedoch nach und nach von Benutzern entdeckte Mängel aufweist). Wie oben erwähnt, reduziere ich jetzt langsam die Verwendung der Nginx+Spawn-Fcgi-Kombination.

Aufgrund der Mängel von spawn-fcgi gibt es jetzt einen PHP-FastCGI-Prozessor PHP-FPM eines Drittanbieters (derzeit zum PHP-Kern hinzugefügt), der mit spawn-fcgi verglichen wird hat folgende Vorteile:
  1. Da es als PHP-Patch entwickelt wurde, muss es während der Installation zusammen mit dem PHP-Quellcode kompiliert werden, was bedeutet, dass es in den PHP-Kern kompiliert wird in Es ist besser in Bezug auf die Leistung;
Gleichzeitig ist es auch besser als spawn-fcgi im Umgang mit hoher Parallelität, zumindest wird der Fastcgi-Prozessor nicht automatisch neu gestartet. Daher wird empfohlen, zum Parsen von PHP die Kombination aus Nginx+PHP/PHP-FPM zu verwenden.

Im Vergleich zu Spawn-FCGI verfügt PHP-FPM über eine bessere CPU- und Speichersteuerung. Ersteres stürzt leicht ab und muss mit crontab überwacht werden, während PHP-FPM keine solchen Probleme verursacht . Der Hauptvorteil von FastCGI besteht darin, dynamische Sprachen vom HTTP-Server zu trennen, sodass Nginx und PHP/PHP-FPM oft auf verschiedenen Servern bereitgestellt werden, um den Druck auf den Front-End-Nginx-Server zu verteilen und Nginx zu ermöglichen verarbeitet ausschließlich statische Anfragen und leitet dynamische Anfragen weiter, während der PHP/PHP-FPM-Server ausschließlich dynamische PHP-Anfragen analysiert.

4. Nginx+PHP-FPM

PHP-FPM ist ein Plugin für PHP Bei der Installation von PHP - Wenn Sie FPM verwenden, müssen Sie PHP-FPM in Form eines Patches in der alten Version von PHP (vor PHP5.3.3) in PHP installieren, und PHP muss mit der PHP-FPM-Version konsistent sein ist ein Muss)

PHP-FPM ist eigentlich ein Patch des PHP-Quellcodes, der darauf abzielt, die FastCGI-Prozessverwaltung in das PHP-Paket zu integrieren. Es muss in Ihren PHP-Quellcode gepatcht werden und kann nach dem Kompilieren und Installieren von PHP verwendet werden.

PHP5.3.3 hat PHP-FPM integriert und ist kein Drittanbieterpaket mehr. PHP-FPM bietet eine bessere PHP-Prozessverwaltungsmethode, kann Speicher und Prozesse effektiv steuern und die PHP-Konfiguration reibungslos neu laden. Es bietet mehr Vorteile als spawn-fcgi und ist daher offiziell in PHP enthalten. Sie können PHP-FPM aktivieren, indem Sie den Parameter –enable-fpm in ./configure übergeben.

Fastcgi ist bereits im Kern von php5.3.5 enthalten. Bei der Konfiguration muss nicht --enable-fastcgi hinzugefügt werden. Ältere Versionen wie PHP5.2 müssen dieses Element hinzufügen.
Wenn wir Nginx und PHP-FPM installieren, sind die Konfigurationsinformationen:

Standardkonfiguration von PHP-FPMphp-fpm.conf:

listen_address 127.0.0.1:9000 #Dies stellt die Überwachungs-IP-Adresse des Fastcgi-Prozesses von PHP dar und Port

start_servers

min_spare_servers

max_spare_servers

Nginx Laufendes PHP konfigurieren: Bearbeiten nginx.conf und fügen Sie die folgende Anweisung hinzu:

               pass 127.0.0.1:9000; gibt den Port an, den der Fastcgi-Prozess überwacht nginx interagiert mit PHP
fastcgi_index index.php;
include fastcgi_params; fastcgi _param SCRIPT_FILENAME /usr /local/nginx/html$fastcgi_script_name;
}



Nginx
Über den Standortbefehl werden alle Dateien mit dem Suffix php Alle von 127.0.0.1:9000 verarbeitet, und die IP-Adresse und der Port sind hier die IP-Adresse und Port, den der FastCGI-Prozess abhört. Sein Gesamtworkflow:

1), FastCGI-Prozessmanager php-fpm initialisiert sich selbst, startet den Hauptprozess php-fpm und startet start_servers Untergeordnete CGI-Prozesse.

Der Hauptprozess php-fpm verwaltet hauptsächlich den Fastcgi-Unterprozess und überwacht Port 9000.

Der untergeordnete fastcgi-Prozess wartet auf eine Verbindung vom Webserver.

2) Wenn die Client-Anfrage den Webserver Nginx erreicht, liefert

Nginx

alle Dateien mit PHP als Suffix über den Standortbefehl „Give it to“. 127.0.0.1:9000 zur Verarbeitung, das heißt Nginx verwendet den Standortbefehl, um alle Dateien mit PHP als Suffix an 127.0.0.1:9000 zur Verarbeitung zu übergeben. 3) Der FastCGI-Prozessmanager PHP-FPM wählt einen untergeordneten Prozess-CGI-Interpreter aus und stellt eine Verbindung zu ihm her. Der Webserver sendet CGI-Umgebungsvariablen und Standardeingaben an den untergeordneten FastCGI-Prozess. 4) Nachdem der FastCGI-Unterprozess die Verarbeitung abgeschlossen hat, gibt er über dieselbe Verbindung Standardausgabe- und Fehlerinformationen an den Webserver zurück. Wenn der untergeordnete FastCGI-Prozess die Verbindung schließt, wird die Anfrage verarbeitet.

5). Der untergeordnete FastCGI-Prozess wartet dann auf die nächste Verbindung vom FastCGI-Prozessmanager (der im WebServer ausgeführt wird).

3. Nginx IO-Modell

Zuallererst ist das von Nginx unterstützte Ereignismodell wie folgt (Nginx-Wiki):

Nginx unterstützt die folgenden Methoden zur Verarbeitung von Verbindungen (I/O-Multiplexing-Methoden). Diese Methoden können über die use-Direktive angegeben werden.

  • select – die Standardmethode. Dies ist die Standardeinstellung zur Kompilierungszeit, wenn es für die aktuelle Plattform keine effizientere Methode gibt. Sie können dieses Modul mit den Konfigurationsparametern –with-select_module und –without-select_module aktivieren oder deaktivieren.
  • Umfrage – die Standardmethode. Dies ist die Standardeinstellung zur Kompilierungszeit, wenn es für die aktuelle Plattform keine effizientere Methode gibt. Sie können dieses Modul mit den Konfigurationsparametern –with-poll_module und –without-poll_module aktivieren oder deaktivieren.
  • kqueue – Effiziente Methode, die in FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 und MacOS
  • epoll – eine effiziente Methode, die in Linux-Kernel-Versionen 2.6 und späteren Systemen verwendet wird. In einigen Distributionen, wie zum Beispiel SuSE 8.2, gibt es einen Patch zur Unterstützung von Epoll im 2.4-Kernel.
  • rtsig – ausführbares Echtzeitsignal, verwendet auf Systemen mit Linux-Kernel-Version 2.2.19 oder höher. Standardmäßig können im gesamten System nicht mehr als 1024 POSIX-Echtzeitsignale (in der Warteschlange) angezeigt werden. Diese Situation ist für stark ausgelastete Server ineffizient; daher ist es notwendig, die Warteschlangengröße durch Anpassen des Kernel-Parameters /proc/sys/kernel/rtsig-max zu erhöhen. Ab der Linux-Kernel-Version 2.6.6-mm2 wird dieser Parameter jedoch nicht mehr verwendet und es gibt eine unabhängige Signalwarteschlange für jeden Prozess. Die Größe dieser Warteschlange kann verwendet werden RLIMIT_SIGPENDING Parameteranpassung. Wenn diese Warteschlange zu überlastet ist, verlässt Nginx sie und beginnt mit der Poll-Methode, um Verbindungen abzuwickeln, bis die Normalität zurückkehrt.
  • /dev/poll – effiziente Methode, verwendet auf Solaris 7 11/99+, HP/UX 11.22+ (Eventport), IRIX 6.5.15+ und Tru64 UNIX 5.1A+
  • Eventport – eine effiziente Methode, die in Solaris 10 verwendet wird. Um Kernel-Abstürze zu verhindern, ist es notwendig, den diesen Sicherheitspatch zu installieren .

Unter Linux ist nur Epoll eine effiziente Methode

Schauen wir uns an, wie effizient Epoll ist
Epoll ist
Linux-Kernel wurde verbessert, um große Stapel von Handles zu verarbeiten Umfrage. Um epoll zu verwenden, benötigen Sie nur diese drei Systemaufrufe: epoll_create(2), epoll_ctl(2), epoll_wait(2). Es wurde im 2.5.44-Kernel eingeführt (epoll(4) ist eine neue API, die im Linux-Kernel 2.5.44 eingeführt wurde) und wird im 2.6-Kernel häufig verwendet.

Vorteile von epoll

  • Unterstützt einen Prozess zum Öffnen einer großen Anzahl von Sockets Deskriptor (FD)

select Das Unerträglichste ist, dass der von einem Prozess geöffnete FD bestimmte Einschränkungen aufweist, die durch FD_SETSIZE festgelegt werden. Der Standardwert ist 2048. Es ist offensichtlich zu wenig für IM-Server, die Zehntausende von Verbindungen unterstützen müssen. Zu diesem Zeitpunkt können Sie zunächst dieses Makro ändern und den Kernel neu kompilieren. Die Daten weisen jedoch auch darauf hin, dass dies zu einer Verringerung der Netzwerkeffizienz führt. Zweitens können Sie eine Multiprozesslösung (traditionelle Apache-Lösung) wählen. Obwohl es unter Linux erstellt wird, sind die Kosten des Prozesses relativ gering, können aber dennoch nicht ignoriert werden. Darüber hinaus ist die Datensynchronisierung zwischen Prozessen weitaus weniger effizient als die Synchronisierung zwischen Threads, sodass es sich nicht um eine vollständige Methode handelt. Schöner Plan. Bei epoll gibt es diese Einschränkung jedoch nicht. Die maximale Anzahl der Dateien, die geöffnet werden können, liegt im Allgemeinen bei 1 GB . Die spezifische Nummer kann lauten: cat /proc Überprüfen Sie /sys/fs/file-max. Im Allgemeinen hat diese Nummer viel mit dem Systemspeicher zu tun.

  • IO-Effizienz nimmt nicht linear mit zunehmender Anzahl von FDs ab

Eine weitere fatale Schwäche traditioneller Auswahl/Umfrage Wenn Sie über eine große Socket-Sammlung verfügen, aufgrund der Netzwerklatenz jedoch immer nur einige der Sockets „aktiv“ sind, wird bei jedem Aufruf von „select/poll“ die gesamte Sammlung linear gescannt, was zu einem linearen Effizienzabfall führt . Aber epoll hat dieses Problem nicht, es funktioniert nur auf „aktiven“ Sockets – das liegt daran, dass epoll in der Kernel-Implementierung basierend auf der Rückruffunktion auf jedem fd implementiert wird. Dann rufen nur „aktive“ Sockets die Rückruffunktion aktiv auf, andere Sockets im Leerlaufzustand jedoch nicht. Zu diesem Zeitpunkt implementiert epoll ein „Pseudo“-AIO, da die treibende Kraft zu diesem Zeitpunkt im Betriebssystemkernel liegt. in einigen Wenn im Benchmark grundsätzlich alle Sockets aktiv sind – beispielsweise in einer Hochgeschwindigkeits-LAN-Umgebung – ist epoll nicht effizienter als select/poll. Im Gegenteil, wenn epoll_ctl zu oft verwendet wird, sinkt die Effizienz leicht. Sobald jedoch inaktive Verbindungen zur Simulation der WAN-Umgebung verwendet werden, ist die Effizienz von Epoll weitaus höher als die von Select/Poll.

  • Verwenden Sie mmap, um den Nachrichtenaustausch zwischen Kernel und Benutzerbereich zu beschleunigen.

Dieser Punkt betrifft tatsächlich die spezifische Implementierung von Epoll. Unabhängig davon, ob es sich um Select, Poll oder Epoll handelt, ist es sehr wichtig, dass der Kernel den Benutzerbereich über die FD-Nachricht informiert, um unnötige Speicherkopien zu vermeiden Kernel. Und wenn Sie wie ich Epoll seit dem 2.5-Kernel verfolgen, werden Sie den manuellen mmap-Schritt bestimmt nicht vergessen.

  • Kernel-Feinabstimmung

Dies ist eigentlich kein Vorteil von Epoll, sondern ein Vorteil des gesamten Linux Plattform. Vielleicht können Sie an der Linux-Plattform zweifeln, aber Sie kommen nicht um die Möglichkeit herum, die Ihnen die Linux-Plattform zur Feinabstimmung des Kernels bietet. Zum Beispiel das KernelTCP/IP-Protokoll Der Stack verwendet einen Speicherpool zur Verwaltung der sk_buff-Struktur, sodass die Größe dieses Speicherpools (skb_head_pool) während der Laufzeit dynamisch angepasst werden kann – erledigt durch echo XXXX>/proc/sys/net/core/hot_list_length. Ein weiteres Beispiel ist der zweite Parameter der Listen-Funktion (die Länge der Paketwarteschlange, nachdem TCP den Drei-Wege-Handshake abgeschlossen hat), der ebenfalls dynamisch an die Speichergröße Ihrer Plattform angepasst werden kann. Wir haben sogar die neueste NAPI-Netzwerkkartentreiberarchitektur auf einem speziellen System ausprobiert, bei dem die Anzahl der Datenpakete riesig, die Größe jedes Pakets selbst jedoch sehr klein ist.

(Epoll-Inhalt, siehe epoll_interactive-Enzyklopädie)

4 🎜>

1. Optimieren Sie den Kompilierungs- und Installationsprozess

1). Reduzieren Sie die Dateigröße von Nginx nach der Kompilierung

Beim Kompilieren von Nginx wird es standardmäßig im Debug-Modus ausgeführt. Im Debug-Modus werden viele Tracking- und ASSERT-Informationen eingefügt. Nach Abschluss der Kompilierung ist ein Nginx mehrere Megabyte groß. Wenn Sie den Debug-Modus von Nginx vor der Kompilierung abbrechen, verfügt Nginx nach der Kompilierung nur über wenige hundert Kilobyte. Daher können Sie vor dem Kompilieren den entsprechenden Quellcode ändern und den Debug-Modus abbrechen. Die spezifische Methode lautet wie folgt:

Nachdem die Nginx-Quellcodedatei dekomprimiert wurde, suchen Sie die Datei auto/cc/gcc im Quellcodeverzeichnis und finden Sie darin die folgenden Zeilen:

  1. # debug  
  2. CFLAGS=”$CFLAGS -g” 
Kommentieren Sie es aus oder löschen Sie es. Löschen Sie diese beiden Zeilen, um den Debug-Modus abzubrechen.

2. Geben Sie die CPU-Typ-Kompilierungsoptimierung für eine bestimmte CPU an

Beim Kompilieren von Nginx ist der Standard-GCC-Kompilierungsparameter „-O“. können die folgenden zwei Parameter verwenden:


  1. --with-cc-opt='-O3' 
  2. --with-cpu-opt=CPU  #为特定的 CPU 编译,有效的值包括:
    pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 
Um den CPU-Typ zu bestimmen, können Sie den folgenden Befehl verwenden:

  1. [root@localhost home]#cat /proc/cpuinfo | grep "model name" 

2. Verwenden Sie TCMalloc zur Optimierung die Leistung von Nginx

TCMallocs vollständiger Name ist Thread-Caching Malloc, ein Mitglied des von Google entwickelten Open-Source-Tools google-perftools. Verglichen mit Malloc der Standard-Glibc-Bibliothek ist die TCMalloc-Bibliothek viel effizienter und schneller bei der Speicherzuweisung, was die Leistung des Servers in Situationen mit hoher Parallelität erheblich verbessert und dadurch die Belastung des Systems verringert. Im Folgenden finden Sie eine kurze Einführung zum Hinzufügen der TCMalloc-Bibliotheksunterstützung zu Nginx.

Um die TCMalloc-Bibliothek zu installieren, müssen Sie die beiden Softwarepakete libunwind (32-Bit-Betriebssysteme müssen nicht installiert werden) und google-perftools installieren. Die libunwind-Bibliothek stellt eine grundlegende Funktionsaufrufkette für Programme bereit basierend auf 64-Bit-CPUs und Betriebssystemen und Funktionsaufrufregisterfunktionen. Im Folgenden wird der spezifische Vorgang der Verwendung von TCMalloc zur Optimierung von Nginx beschrieben.

1). Installieren Sie die libunwind-Bibliothek

Sie können die entsprechende libunwind-Version von http://download.savannah.gnu.org/releases/libunwind herunterladen hier ist es libunwind-0.99-alpha.tar.gz. Der Installationsprozess ist wie folgt:


  1. [root@localhost home]#tar zxvf libunwind-0.99-alpha.tar.gz  
  2. [root@localhost home]# cd libunwind-0.99-alpha/  
  3. [root@localhost libunwind-0.99-alpha]#CFLAGS=-fPIC ./configure  
  4. [root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC  
  5. [root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC install 

2). Um google-perftools

zu installieren, können Sie das entsprechende von http://google -perftools.googlecode.com Die hier heruntergeladene Google-perftools-Version ist google-perftools-1.8.tar.gz. Der Installationsprozess läuft wie folgt ab:

  1. [root@localhost home]#tar zxvf google-perftools-1.8.tar.gz  
  2. [root@localhost home]#cd google-perftools-1.8/  
  3. [root@localhost google-perftools-1.8]# ./configure  
  4. [root@localhost google-perftools-1.8]#make && make install  
  5. [root@localhost google-perftools-1.8]#echo "/usr/
    local/lib" 
    > /etc/ld.so.conf.d/usr_local_lib.conf  
  6. [root@localhost google-perftools-1.8]# ldconfig 
An diesem Punkt ist die Installation von google-perftools abgeschlossen.

3). Kompilieren Sie Nginx neu

Damit Nginx google-perftools unterstützt, müssen Sie während des Installationsprozesses die Option „-with-google_perftools_module“ hinzufügen Nginx neu kompilieren. Der Installationscode lautet wie folgt:

  1. [root@localhostnginx-0.7.65]#./configure \  
  2. >--with-google_perftools_module --with-http_stub_status_module  --prefix=/opt/nginx  
  3. [root@localhost nginx-0.7.65]#make  
  4. [root@localhost nginx-0.7.65]#make install 
Hier ist die Nginx-Installation abgeschlossen.

4) Fügen Sie ein Thread-Verzeichnis für google-perftools hinzu

Erstellen Sie ein Thread-Verzeichnis und platzieren Sie die Datei unter /tmp/tcmalloc. Der Vorgang ist wie folgt:

  1. [root@localhost home]#mkdir /tmp/tcmalloc  
  2. [root@localhost home]#chmod 0777 /tmp/tcmalloc 

5). Ändern Sie die Nginx-Hauptkonfigurationsdatei

Ändern Sie die Datei nginx.conf und fügen Sie den folgenden Code unter der PID hinzu Zeile:

  1. #pid        logs/nginx.pid;  
  2. google_perftools_profiles /tmp/tcmalloc; 
Dann starten Sie Nginx neu, um das Laden von google-perftools abzuschließen.

6). Überprüfen Sie den Ausführungsstatus

Um zu überprüfen, ob google-perftools normal geladen wurde, können Sie es mit dem folgenden Befehl anzeigen:

  1. [root@ localhost home]# lsof -n | grep tcmalloc  
  2. nginx      2395 nobody   9w  REG    8,8       0    1599440 /tmp/tcmalloc.2395  
  3. nginx      2396 nobody   11w REG   8,8       0    1599443 /tmp/tcmalloc.2396  
  4. nginx      2397 nobody   13w REG  8,8        0    1599441  /tmp/tcmalloc.2397  
  5. nginx     2398 nobody    15w REG  8,8     0    1599442 /tmp/tcmalloc.2398 
Da in Der Wert von worker_processes ist in der Nginx-Konfigurationsdatei auf 4 gesetzt, sodass 4 Nginx-Threads geöffnet werden und jeder Thread eine Zeile mit Datensätzen hat. Der numerische Wert nach jeder Thread-Datei ist der PID-Wert des gestarteten Nginx.

An diesem Punkt ist die Verwendung von TCMalloc zur Optimierung von Nginx abgeschlossen.

3. Nginx-Kernel-Parameteroptimierung

Die Optimierung von Kernel-Parametern ist hauptsächlich die Optimierung von Systemkernel-Parametern für Nginx-Anwendungen in Linux-Systemen.

Ein Optimierungsbeispiel finden Sie unten als Referenz.

  1. net.ipv4.tcp_max_tw_buckets = 6000 
  2. net.ipv4.ip_local_port_range = 1024 65000  
  3. net.ipv4.tcp_tw_recycle = 1 
  4. net.ipv4.tcp_tw_reuse = 1 
  5. net.ipv4.tcp_syncookies = 1 
  6. net.core.somaxconn = 262144 
  7. net.core.netdev_max_backlog = 262144 
  8. net.ipv4.tcp_max_orphans = 262144 
  9. net.ipv4.tcp_max_syn_backlog = 262144 
  10. net.ipv4.tcp_synack_retries = 1 
  11. net.ipv4.tcp_syn_retries = 1 
  12. net.ipv4.tcp_fin_timeout = 1 
  13. net.ipv4.tcp_keepalive_time = 30 

Fügen Sie die oben genannten Kernel-Parameterwerte zur Datei /etc/sysctl.conf hinzu und führen Sie dann den folgenden Befehl aus, um sie wirksam zu machen:

  1. [root@ localhost home]#/sbin/sysctl -p 

下面对实例中选项的含义进行介绍:

net.ipv4.tcp_max_tw_buckets选项用来设定timewait的数量,默认是180 000,这里设为6000。

net.ipv4.ip_local_port_range选项用来设定允许系统打开的端口范围。

net.ipv4.tcp_tw_recycle选项用于设置启用timewait快速回收。

net.ipv4.tcp_tw_reuse选项用于设置开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_syncookies选项用于设置开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies进行处理。

net.core.somaxconn选项的默认值是128, 这个参数用于调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此,需要结合并发请求数来调节此值。

net.core.netdev_max_backlog选项表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。

net.ipv4.tcp_max_orphans选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立连接将立即被复位并打印出警告信息。这个限制只是为了防止简单的DoS攻击。不能过分依靠这个限制甚至人为减小这个值,更多的情况下应该增加这个值。

net.ipv4.tcp_max_syn_backlog选项用于记录那些尚未收到客户端确认信息的连接请求的最大值。对于有128MB内存的系统而言,此参数的默认值是1024,对小内存的系统则是128。

net.ipv4.tcp_synack_retries参数的值决定了内核放弃连接之前发送SYN+ACK包的数量。

net.ipv4.tcp_syn_retries选项表示在内核放弃建立连接之前发送SYN包的数量。

net.ipv4.tcp_fin_timeout选项决定了套接字保持在FIN-WAIT-2状态的时间。默认值是60秒。正确设置这个值非常重要,有时即使一个负载很小的Web服务器,也会出现大量的死套接字而产生内存溢出的风险。

net.ipv4.tcp_syn_retries选项表示在内核放弃建立连接之前发送SYN包的数量。

如果发送端要求关闭套接字,net.ipv4.tcp_fin_timeout选项决定了套接字保持在FIN-WAIT-2状态的时间。接收端可以出错并永远不关闭连接,甚至意外宕机。

net.ipv4.tcp_fin_timeout的默认值是60秒。需要注意的是,即使一个负载很小的Web服务器,也会出现因为大量的死套接字而产生内存溢出的风险。FIN-WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能消耗1.5KB的内存,但是其生存期长些。

net.ipv4.tcp_keepalive_time选项表示当keepalive启用的时候,TCP发送keepalive消息的频度。默认值是2(单位是小时)。

4. PHP-FPM的优化

如果您高负载网站使用PHP-FPMFastCGI,这些技巧也许对您有用:

1)增加FastCGI进程数

PHP FastCGI子进程数调到100或以上,4G内存的服务器上200就可以建议通过压力测试获取最佳值。

2)增加 PHP-FPM打开文件描述符的限制

标签rlimit_files用于设置PHP-FPM对打开文件描述符的限制,默认值为1024。这个标签的值必须和Linux内核打开文件数关联起来,例如,要将此值设置为65 535,就必须在Linux命令行执行“ulimit -HSn 65536”。

       然后 增加 PHP-FPM打开文件描述符的限制:
     # vi /path/to/php-fpm.conf
    找到
1024”
1024更改为 4096或者更高
.
重启 PHP-FPM.

         3)适当增加max_requests

    标签max_requests指明了每个children最多处理多少个请求后便会被关闭,默认的设置是500。

     500

   

5.   Nginx的php漏洞

Einführung in die Sicherheitslücke: Nginx ist ein weit verbreiteter Hochleistungs-Webserver. Er wird nicht nur häufig als Reverse-Proxy verwendet, sondern kann auch den Betrieb von PHP sehr gut unterstützen. 80sec hat festgestellt, dass ein schwerwiegendes Sicherheitsproblem vorliegt. Standardmäßig kann der Server jede Art von Datei in PHP falsch analysieren. Dies führt zu schwerwiegenden Sicherheitsproblemen und ermöglicht es böswilligen Angreifern, Nginx zu kompromittieren.


Schwachstellenanalyse: Nginx unterstützt standardmäßig die Ausführung von PHP im CGI-Modus. In der Konfigurationsdatei können Sie beispielsweise

location ~ .php$ {<code><br>location ~ .php$ {<br>root html;<br>fastcgi_pass 127.0.0.1:9000;<br>fastcgi_index index.php;<br>fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;<br>include fastcgi_params;<br>}<br>root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;include fastcgi_params;

}

unterstützt das Parsen von PHP. Wenn der Standort eine Anfrage auswählt, wird die an das Backend Fastcgi übergebene Schlüsselvariable SCRIPT_FILENAME durch den von generierten $fastcgi_script_name bestimmt nginx und Durch Analyse können wir sehen, dass $fastcgi_script_name direkt von der URI-Umgebungsvariablen gesteuert wird. Hier entsteht das Problem. Um die Extraktion von PATH_INFO besser zu unterstützen, gibt es in den PHP-Konfigurationsoptionen die Option cgi.fix_pathinfo. Ihr Zweck besteht darin, den tatsächlichen Skriptnamen aus SCRIPT_FILENAME zu extrahieren.

Angenommen, es gibt http://www.80sec.com/80sec.jpg, greifen wir auf folgende Weise auf



<br>/80sec.jpg/80sec.php<br>http://www.80sec zu. com/80sec.jpg/80sec.php

<br>/scripts/80sec.jpg/80sec.php<br>
erhält einen URI
<code><br>/scripts/80sec.jpg<br>/80sec.jpg/80sec.php

Nach dem Standortbefehl wird die Anfrage zur Verarbeitung an das Back-End-Fastcgi übergeben, und Nginx legt dafür die Umgebungsvariable SCRIPT_FILENAME mit dem Inhalt von
<code><br>/scripts/80sec.jpg和80sec.php<br>/scripts/80sec fest. jpg/80sec.php

Bei anderen Webservern wie lighttpd haben wir festgestellt, dass SCRIPT_FILENAME korrekt auf

/scripts/80sec.jpg

eingestellt ist. Code>
Es gibt also kein solches Problem. <br>HTTP/1.1 200 OK<br>Server: nginx/0.6.32<br>Date: Thu, 20 May 2010 10:05:30 GMT<br>Content-Type: text/plain<br>Content-Length: 18<br>Last-Modified: Thu, 20 May 2010 06:26:34 GMT<br>Connection: keep-alive<br>Keep-Alive: timeout=20<br>Accept-Ranges: bytes<br>Wenn das Backend-Fastcgi diese Option empfängt, entscheidet es basierend auf der fix_pathinfo-Konfiguration, ob eine zusätzliche Verarbeitung für SCRIPT_FILENAME durchgeführt werden soll. Wenn fix_pathinfo nicht festgelegt ist, wirkt sich dies im Allgemeinen auf Anwendungen aus, die PATH_INFO für die Routing-Auswahl verwenden, daher ist dies der Fall im Allgemeinen zum Einschalten konfiguriert. Nach Übergabe dieser Option sucht PHP auch nach dem tatsächlichen Namen der Skriptdatei. Zu diesem Zeitpunkt werden SCRIPT_FILENAME und PATH_INFO in
<br>/scripts/ unterteilt. 80sec.jpg bzw. 80sec. php<code><br>HTTP/1.1 200 OK<br>Server: nginx/0.6.32<br>Date: Thu, 20 May 2010 10:06:49 GMT<br>Content-Type: text/html<br>Transfer-Encoding: chunked<br>Connection: keep-alive<br>Keep-Alive: timeout=20<br>X-Powered-By: PHP/5.2.6<br>
Mit /scripts/80sec.jpg schließlich kann der Angreifer nginx PHP zum Parsen verwenden lassen Art der Datei.

POC: Besuchen Sie eine Website, auf der Nginx PHP unterstützt, und fügen Sie /80sec.php nach einer Ressourcendatei wie robots.txt hinzu. Zu diesem Zeitpunkt können Sie den folgenden Unterschied erkennen:

Besuchen http://www.80sec.com/robots.txt

<p>HTTP/1.1 200 OK<br>Server: nginx/0.6.32<code><br>关闭cgi.fix_pathinfo为0<br>Datum: Do, 20. Mai 2010 10:05 :30 GMT
Inhaltstyp: Text/Plain
Inhaltslänge: 18<br>if ( $fastcgi_script_name ~ ..*/.*php ) {<br>return 403;<br>}<br>Letzte Änderung: Do, 20. Mai 2010 06:26:34 GMT

Verbindung: keep-alive

Keep-Alive: Timeout=20

Accept-Ranges: Bytes

Besuchen Sie http://www.80sec.com/robots.txt/80sec.php

HTTP/1.1 200 OKServer: nginx/0.6.32Datum: Do, 20. Mai 2010 10:06:49 GMTInhaltstyp: text/htmlÜbertragungskodierung: chunkedVerbindung: keep-aliveKeep-Alive: timeout=20X-Powered-By: PHP/5.2.6Inhalt – Änderungen im Typ weisen auf Änderungen hin liegt in der Verantwortung des Backends für das Parsen, und es können Schwachstellen auf der Website vorhanden sein. Anbieter der Sicherheitslücke: http://www.nginx.orgLösung: Wir haben versucht, den Beamten zu kontaktieren, aber vorher können Sie Verluste wie folgt reduzieren Methoden Cgi.fix_pathinfo auf 0 schließenoder if ( $fastcgi_script_name ~ ..*/.*php ) { return 403;}PS: Vielen Dank an Laruence Daniel für seine Hilfe während des Analyseprozesses Das Obige stellt das Arbeitsprinzip, die Optimierung und die Lücken von Nginx vor. Ich hoffe, dass es Freunden, die sich für PHP-Tutorials interessieren, hilfreich sein wird, einschließlich relevanter Inhalte.
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn