Nginx ist ein sehr beliebter und ausgereifter Webserver und Reserve-Proxy-Server. Es gibt eine große Anzahl von Tutorials zur Leistungsoptimierung. Welche Konfiguration für Sie am besten geeignet ist, ist jedoch sehr unterschiedlich viel Testen und Üben und kontinuierliche Optimierung und Verbesserung. Nachdem die Anzahl der Benutzeranrufe kürzlich eine Million überschritten hatte, stießen wir auf einige Probleme. Obwohl sie nicht allzu kompliziert waren, dauerte es lange, sie zu lösen, und wir sammelten viel Erfahrung.
Dieses Problem besteht tatsächlich schon seit einiger Zeit. Einige Kunden haben uns berichtet, dass die Anrufzeit abgelaufen ist, aber laut unserer eigenen Systemüberwachung ist es nur ein paar zehn Millisekunden Es wird definitiv keine Zeitüberschreitung geben, ich bezweifelte, dass es am Netzwerk lag, aber nachdem es ein paar Mal passiert war, hatte ich das vage Gefühl, dass dieses Problem möglicherweise kein Zufall war und dass es tiefgreifende Gründe haben sollte.
Da sich unser Service an Unternehmenskunden richtet, verfügt jeder Unternehmenskunde nur über wenige öffentliche Netzwerk-IPs, obwohl das Anrufvolumen jedes Kunden sehr groß sein kann. Selbst wenn es in Zukunft Tausende von Kunden geben wird, kann Nginx dies tun Unterstützen Sie diese gleichzeitigen Verbindungen problemlos. Daher haben wir zunächst die lange Nginx-Verbindung aus dem Netzwerk optimiert, die lange Verbindung von der ursprünglichen Konfiguration von 5秒钟
auf 5分钟
geändert und die Anzahl der Verbindungsanfragen jedes Mal vom Standardwert 100 auf 1000 angepasst.
<code>keepalive_timeout 300; keepalive_requests 1000;</code>
Nachdem die Anpassung abgeschlossen ist, können Sie über den Befehl netstat
-anp
sehen, dass die Anzahl neuer Verbindungsanfragen abnimmt, was darauf hinweist, dass die lange Verbindung funktioniert hat. Aber nach einer Weile wurde immer noch festgestellt, dass es bei Kundenanrufen zu Zeitüberschreitungen kam. Aus dem Nginx-Protokoll können wir ersehen, dass die Anfragezeit immer noch mehr als 1 Sekunde beträgt und einige sogar bis zu 20 Sekunden dauern, wie unten gezeigt:
Und bei der Überwachung auf Zabbix wurde ein Phänomen entdeckt: Wenn die Anzahl der Verbindungsschreibvorgänge oder -aktiven plötzlich zunimmt, kommt es entsprechend mehr Zeitüberschreitungen bei der Anforderungszeit:
Beim Blick auf das Anwendungsprotokoll haben wir festgestellt, dass die Ausführungszeit nicht lang ist:
Die in der gezählte Zeit Die Anwendung erfolgt nur vom Beginn des Geschäfts an. Die Zeit von der Ausführung bis zum Ausführungsergebnis beinhaltet nicht die Ausführungszeit des Tomcat-Containers. Der Ausführungspfad der externen Anforderung lautet wie folgt:
<code>client --> Nginx --> Tomcat --> App</code>
Könnte es sein dass es ein Problem mit der Ausführung des Tomcat-Containers selbst gibt? Legen Sie das Protokoll der Tomcat-Anfrage ab. Nach dem Aufruf haben wir festgestellt, dass die Ausführung vor und nach diesem Zeitpunkt ebenfalls normal ist:
Aus der Analyse des Anforderungspfads geht hervor, dass es auf der Nginx-zu-Tomcat-Ebene einige Probleme geben muss. Bei der Behebung dieses Problems habe ich plötzlich eine große Anzahl von Zeitüberschreitungen von etwa 30 Sekunden festgestellt. Es wurde auch von Zabbix beobachtet, dass connection
writing
sehr hoch war, wie unten gezeigt:
Gleichzeitig haben wir festgestellt, dass TIME_WAIT
über eine besonders große Anzahl von Verbindungen verfügt. Aus den Ergebnissen der Paketerfassungsanalyse geht hervor, dass einige Kunden anscheinend keine langen Verbindungen aktiviert haben, und wir haben bis zu 5 Minuten auf dem Server, was zu einer großen Anzahl von Verbindungswartezeiten führte. Zu diesem Zeitpunkt waren es fast 2000. Bearbeiten Sie die Datei keepalive_timeout
und fügen Sie die folgenden zwei Parameter hinzu, um die Verbindung wiederzuverwenden 🎜>/etc/sysctl.conf
Nach dem Inkrafttreten fiel der Wert schnell auf unter 200. Dies ist auch aus der Zabbix-Überwachung ersichtlich. Sowohl
<code>net.ipv4.tcp_tw_reuse = 1 #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。</code>
connection
writing
Nginx's
bezieht sich auf die Zeit vom ersten vom Client empfangenen Byte bis zum Upstream des aufrufenden Backends
Die Zeit, bis der Server die Verarbeitung der Geschäftslogik abschließt und alle zurückgegebenen Ergebnisse an den Client zurückschreibt. Wenn die Zeit des Aufrufs des Upstream-Servers gedruckt werden kann, ist es einfacher, den Umfang des Problems einzugrenzen Parameter, die gedruckt werden können. Die vom Backend-Server angeforderte Zeit und IP-Adresse. Ändern Sie das Protokollformat in der Datei nginx.conf wie folgt:
reqeust_time
Wenn Sie sich das Protokoll noch einmal ansehen, ist dies sehr offensichtlich Die meisten besonders langen Anrufe kommen vom selben Server:
<code># $upstream_response_time 后端应用服务器响应时间 # $upstream_addr 后端服务器IP和端口号 log_format main '$remote_addr - [$time_local] "$request" ' '$status $body_bytes_sent ' '"$request_time" "$upstream_response_time" "$upstream_addr" "$request_body "';</code>
Beim Betrachten dieser Maschine stellte ich fest, dass der Java-Prozess zwar immer noch vorhanden ist, die Anwendung ist tatsächlich abgestürzt und es sind keine echten Anfragen eingegangen. Entfernen Sie es aus. Entfernen Sie es während des Lastausgleichs, und das Problem wird sofort behoben:
Diese Maschine ist tatsächlich hängengeblieben up, aber warum hat Nginx es nicht erkannt? Weitere Untersuchungen ergaben, dass das Standard-Timeout bei Nginx-Aufrufen 60 Sekunden beträgt. Daher ist es sinnlos, das Standard-Timeout in der Datei nginx.conf zu ändern und zurückzugeben überschreitet 1s. :
<code># time out settings proxy_connect_timeout 1s; proxy_send_timeout 1s; proxy_read_timeout 1s;</code>
request_time
超过1s达到5s的,但upstream_response_time
都没有超时了,说明上面的参数已起作用。
版权声明:本文为博主原创文章,未经博主允许不得转载。
以上就介绍了Nginx 性能优化,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。