Spezifische Verwendung von Nginx Keepalive

Spezifische Verwendung von Nginx Keepalive

Der Standardanforderungsheader des http1.1-Protokolls aktiviert standardmäßig Keepalive, wie in der Abbildung dargestellt:

Was ist also Keepalive? Was ist die Funktion?

Keepalive ist ein Mechanismus in TCP, der tote Verbindungen erkennen kann. Seine Funktion besteht darin, zu verhindern, dass die Socket-Verbindung getrennt wird. Es gehört zur TCP-Schicht und nicht zur Anwendungsschicht.

Wie hält die TCP-Schicht eine lange Verbindung aufrecht?

Schauen wir uns zunächst die Verwendung von Keepalive an: Es gibt drei Parameter, die für die Anwendungsschicht offen sind

sk->keepalive_probes: Anzahl der Probes, Anzahl der Wiederholungsversuche sk->keepalive_time: Heartbeat-Intervall des Probes, nach wie vielen Sekunden die TCP-Verbindung die Probe-Nachricht startet, ohne Datenpakete zu übertragen sk->keepalive_intvl: Probe-Intervall, das Zeitintervall zwischen Wiederholungsversuchen, wenn keine Antwort empfangen wird

Standardkonfigurationsansicht:

[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

Anwendung:

int keepalive = 1; // Aktiviere das Keepalive-Attribut int keepidle = 60; // Wenn innerhalb von 60 Sekunden kein Datenaustausch stattfindet, wird eine Erkennung durchgeführt int keepinterval = 5; // Das Intervall zwischen dem Senden von Paketen während der Erkennung beträgt 5 Sekunden int keepcount = 3; // Die Anzahl der Erkennungsversuche. Wenn nach dem ersten Erkennungspaket eine Antwort empfangen wird, werden die nächsten beiden Erkennungspakete nicht gesendet. Und lösche den Zähler setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));
setockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle, Größe von(keepidle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval, Größe von(keepinterval));
setockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount, Größe von(keepcount));

Nachdem die Anwendungsschicht auf diese Weise eingerichtet wurde, wird die Standardkonfiguration überschrieben und die manuell festgelegte Konfiguration verwendet.

Für eine hergestellte TCP-Verbindung. Wenn innerhalb des Zeitraums „keepalive_time“ keine Datenpaketübertragung zwischen den beiden Parteien stattfindet, sendet das Ende mit aktivierter Keepalive-Funktion ein Keepalive-Daten-Heartbeat-Paket. Wenn keine Antwort empfangen wird, wird das Paket jedes Mal „keepalive_intvl“ erneut gesendet und es werden „keepalive_probes“-Zeiten gesendet. Wenn keine Antwort eingeht, wird ein erstes Paket gesendet, um die Verbindung zu schließen. Wenn eine Antwort eingeht, wird der Timer gelöscht.

Erfassen Sie das Paket, um den Inhalt des TCP-Heartbeat-Pakets zu überprüfen

Analysieren Sie weiterhin die von Keepalive gesendeten und beantworteten Heartbeat-Pakete basierend auf den erfassten Paketen:

Der Quellcode der TCP-Headerstruktur lautet:

Typdefinitionsstruktur _TCP_HEADER
{
 short m_sSourPort; // Quellportnummer 16bit
 short m_sDestPort; // Zielportnummer 16bit
 unsigned int m_uiSequNum; //erforderliche Feldsequenznummer 32 Bit
 unsigned int m_uiAcknowledgeNum; //ack-Feld Bestätigungsnummer 32bit
 short m_sHeaderLenAndFlag; // Die ersten 4 Bits: TCP-Headerlänge; die mittleren 6 Bits: reserviert; die letzten 6 Bits: Flag short m_sWindowSize; // Fenstergröße des Win-Fields 16 Bits
 short m_sCheckSum; // Prüfsumme 16bit
 short m_surgentPointer; // Notfalldaten-Offset 16 Bit
}__attribute__((gepackt))TCP_HEADER, *PTCP_HEADER;

Sehen Sie sich den Inhalt des gesendeten Heartbeat-Pakets an:

0000 d4 6d 50 f5 02 7f f4 5c 89 cb 35 29 08 00 // MAC-Header 14 Bytes:
                         45 00 // IP-Header 20 Bytes:
0010 00 28 10 f4 00 00 40 06 5b dd ac 19 42 76 0a b3
0020 14 bd
      e4 4a 1f 7c 32 7e 7a cb 4c bc 55 08 50 10 // TCP-Header 20 Bytes 0030 10 00 3f 00 00 00
//Analysieren Sie den Inhalt des TCP-Headers e4 4a //Die Quellportnummer 16bit dezimal lautet: 58442 
1f 7c //Zielportnummer 16bit dezimal: 8060 
32 7e 7a cb // Die 32-Bit-Seriennummer des Req-Feldes ist dezimal: 
4c bc 55 08 // ack-Feld Bestätigungsnummer 32 Bit 
5 // Erste 4 Bits: TCP-Headerlänge 5*4 = 20 Bytes, kein Problem 0 10 /// Mittlere 6 Bits: reserviert; letzte 6 Bits: Flag-Bit 10 stellt dar, dass das 5. Bit vom Ende 1 ist und die Änderung des TCP-Pakets in ein ACK-Bestätigungspaket kennzeichnet 0030 10 00 3f 00 00 00

Schauen Sie sich weiterhin den Inhalt des geantworteten Heartbeat-Pakets an:

0000 f4 5c 89 cb 35 29 d4 6d 50 f5 02 7f 08 00 45 00 
0010 00 34 47 28 40 00 36 06 ef 9c 0a b3 14 bd ac 19 
0020 42 76 // Die vorherigen Daten werden nicht interpretiert 1f 7c
e4 4a
4c bc 55 08
32 7e 7a cc
8 // Die Länge des TCP-Headers beträgt 8 * 4 = 32. Zusätzlich zum Header gibt es 12 Bytes optionale Daten. 0 10 // Die mittleren 6 Bits sind reserviert; die letzten 6 Bits sind Flag-Bits. 10 steht dafür, dass das 5. Bit vom Ende 1 ist, was darauf hinweist, dass das TCP-Paket ein ACK-Bestätigungspaket ist. 0030 01 3f // Die Win-Field-Fenstergröße beträgt 16 Bits.
4e 0d // Prüfsumme 16bit
00 00 // Notfalldaten-Offset 16 Bit
01 01 08 0a 00 59 be 1c 39 13 
0040 cf 12 // Optionsdaten 12 Bytes

Wie aus dem Obigen ersichtlich ist, besteht das Heartbeat-Paket von TCP zur Aufrechterhaltung einer langen Verbindung darin, dass der Browser zuerst ein ACK-Paket an den Server sendet und der Server dann mit einem ACK-Paket mit Optionsdaten antwortet

Wie verarbeitet Nginx Keepalive-Anfragen und was macht es?

Als erstes muss die Version ermittelt werden: Wenn die HTTP-Protokollversion niedriger als 1.1 ist, wird das Keepalive des Links auf 0 gesetzt
wenn (r->http_version < NGX_HTTP_VERSION_11) {
  r->keepalive = 0;
} 
Wenn ngx_http_process_connection in der Funktion ngx_http_request_t über Keep-Alive verfügt, markieren Sie den Link, wenn (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
  r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
}
In der Funktion ngx_http_handler wird r->headers_in.connection_type beurteilt und r->keepalive wird der Wert 1 zugewiesen.
  Schalter (r->Header_in.Verbindungstyp) {
  Fall NGX_HTTP_CONNECTION_KEEP_ALIVE:
    r->live bleiben = 1;
    brechen;
  }
Wenn Keepalive in der Funktion ngx_configure_listening_sockets 1 ist, wird KEEPALIVE für die Verbindung aktiviert. Danach erkennt die zugrunde liegende TCP-Schicht tote Verbindungen für die Verbindung fd, hält eine lange Verbindung aufrecht und trennt sie nicht.
wenn (ls[i].keepalive) {
  Wert = (ls[i].keepalive == 1) ? 1 : 0;

  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,//Keepalive-Funktion aktivieren (const void *) &value, sizeof(int))
    == -1)
  
}

Wann wird die Nginx-Langverbindung getrennt?

Nachdem nginx Keepalive über setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,(const void *) &value, sizeof(int)) aktiviert hat, wird es immer eine lange Verbindung mit dem Client aufrechterhalten. Dies führt zu einem ernsthaften Problem. Die Anzahl der Verbindungen, die jeder Woker aufrechterhalten kann, ist begrenzt (ep = epoll_create(cycle->connection_n / 2); cycle->connection_n / 2 ist die Obergrenze des FD, das epoll verwalten kann). Auf diese Weise wird die Anzahl der Verbindungen schnell erschöpft sein. Was sollte nginx zu diesem Zeitpunkt tun?

Um die Antwort zu finden, schauen wir uns zwei Nginx-Konfigurationsparameter für Keeoalive an.

Keepalive_Timeout

keepalive_timeout Zeitüberschreitung [Header_Timeout];

Der erste Parameter: Legt den Timeout-Wert für die Keep-Alive-Client-Verbindung fest, die auf der Serverseite offen bleiben soll (standardmäßig 75 s); ein Wert von 0 deaktiviert die Keep-Alive-Client-Verbindung;

Der zweite Parameter: optional, legen Sie im Antwortheaderfeld einen Wert „Keep-Alive: timeout=time“ fest; normalerweise muss dieser nicht festgelegt werden;

Hinweis: keepalive_timeout beträgt standardmäßig 75 s

Keepalive-Anfragen

Mit der Direktive „keepalive_requests“ wird die maximale Anzahl von Anfragen festgelegt, die über eine Keep-Alive-Verbindung bedient werden können. Wenn die maximale Anzahl von Anfragen erreicht ist, wird die Verbindung geschlossen. Ein Wert von 0 deaktiviert auch Keep-Alive-Clientverbindungen. Der Standardwert ist 100.
Die Antwort liegt auf der Hand. Verwenden Sie keepalive_timeout keepalive_requests, um lange Verbindungen zu verwalten.

  • Wenn eine TCP-Verbindung länger als das „keepalive_timeout“ besteht, wird sie geschlossen. Nginx implementiert dies über einen Timer.
  • Wenn die maximale Anzahl von Liebesbriefen einer TCP-Verbindung die Anzahl der Keepalive_Requests überschreitet, wird sie ebenfalls geschlossen

Diese beiden Mechanismen stellen sicher, dass die Anzahl der Verbindungen für jeden Worker die Anzahl nicht überschreitet, die Epoll verwalten kann.

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der hochverfügbaren Master-Slave-Konfiguration von nginx+keepalived
  • Detaillierte Erklärung von Keepalived+Nginx zum Erreichen hoher Verfügbarkeit (HA)
  • Nginx + Keepalived realisiert Hot-Standby von Dual-Maschinen
  • So kombinieren Sie Keepalived mit Nginx, um eine hohe Verfügbarkeit von Nginx zu erreichen
  • Konfigurationsmethode für Keepalived Dual-Machine Hot Standby Nginx
  • Keepalived implementiert Hochverfügbarkeit von nginx
  • Detaillierte Erklärung der HTTP-Keepalive-Konfiguration in Nginx

<<:  Tutorial zur Installation von MySQL 5.6 auf CentOS 6.5

>>:  Layim in Javascript, um Freunde und Gruppen zu finden

Artikel empfehlen

CSS3 realisiert eine springende Ballanimation

Normalerweise besuche ich gerne die Sonderseiten ...

Detaillierter Prozess zum Dekomprimieren und Installieren von mysql5.7.17 zip

1. Adresse herunterladen https://dev.mysql.com/do...

MySQL 8.0.19 Installations- und Konfigurations-Tutorial unter Windows 10

Ich werde nächstes Semester MySQL lernen. Ich hab...

Nodejs-Fehlerbehandlungsprozessaufzeichnung

In diesem Artikel wird der Verbindungsfehler ECON...

MySQL verwendet Aggregatfunktionen zum Abfragen einer einzelnen Tabelle

Aggregatfunktionen Wirkt auf einen Datensatz ein ...

MySQL implementiert den Vorgang zum Festlegen mehrerer Primärschlüssel

Benutzertabelle, ID-Nummer muss eindeutig sein, M...

Docker verwendet Supervisor zur Verwaltung von Prozessvorgängen

Ein Docker-Container startet beim Start beispiels...