Kernel-Socket-Struktur und TCP_DIAG


18

Ich arbeite an einer Software, die eine Verbindung zu einem Echtzeit-Datenserver (über TCP) herstellt, und es treten Verbindungsabbrüche auf. Ich vermute, dass die Clients die vom Server kommenden Daten nicht schnell genug lesen. Deshalb möchte ich meine TCP-Sockets überwachen. Dafür habe ich das "ss" Tool gefunden.

Mit diesem Tool können Sie den Status aller Sockets anzeigen. Hier ist ein Beispiel für die Ausgabe des Befehls ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

Meine Frage ist: Was bedeutet der Erinnerungsteil? Beim Betrachten des Quellcodes des Tools stellte ich fest, dass die Daten aus einer Kernelstruktur ( sockin sock.h) stammen. Genauer gesagt kommt es von den Feldern:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

Weiß jemand, was sie bedeuten? Meine Vermutungen sind:

  • rmem_alloc : Größe des Eingangspuffers
  • wmem_alloc : Größe des ausgehenden Puffers
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Hier sind meine Puffergrößen:

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071

Was ist Ihre Puffergrößenkonfiguration? Sehen Sie Empfangspuffer, die auf den Socket-Verbindungen gesättigt werden? Trennt Ihre Partei die Verbindung zu EWOULDBLOCK?
Karlson

Meine Sockelgrößen sind ziemlich klein, ich denke, ich habe den Beitrag mit ihnen aktualisiert. Zum EWOULDBLOCK kann ich nichts sagen. Mein Client ist in JAVA und sagt einfach, dass er vom Server getrennt wurde. Der Server ist in C ++ und es heißt nur, dass er die Verbindung ohne Informationen getrennt hat. Ich habe den Quellcode des Servers nicht, daher kann ich sein Verhalten nicht ändern. Es scheint, dass Clients getrennt werden, wenn sie etwas überlastet sind, auch wenn dies nur einige Sekunden dauert.
Twister

Ist die Konfiguration der Puffergrößen auf dem Server einstellbar? Können Sie die Puffergrößen auf dem Client anzeigen? Haben Sie Zugriff auf die Quelle des Kunden? Haben Sie netstat -apnc ausgeführt, um die Puffergrößen zu überwachen? Haben Sie versucht, die Puffergröße im Kernel zu erhöhen, um zu sehen, was passiert?
Karlson

Ja, und sie sind bereits auf den Maximalwert des Servers eingestellt (ich glaube, sie können nicht größer sein als die Eigenschaften von net.ipv4.tcp_ *, oder?). Für netstat -apnc gibt es keine Puffergrößen. deshalb habe ich ss angeschaut. Für den Kernel bin ich nicht root auf dem Server und die IT-Teams hier sind ziemlich hartnäckig. Ich muss sicher sein, was passiert, bevor ich sie auffordere, die Werte zu ändern ... Und ja, ich habe Zugriff auf die Clientquelle, und meine Untersuchungen am Client bestätigen, dass die Trennung vom Server erfolgt.
Twister

Mit netstat -apnc erhalten Sie die Gesamtgröße der Sende- und Empfangswarteschlangen unter Linux. Wenn der Server den Puffer auf den maximal verfügbaren Wert setzt und Sie immer noch gesättigt sind, benötigen Sie möglicherweise höhere Puffereinstellungen auf Betriebssystemebene
Karlson

Antworten:


7

sk_forward_alloc ist der vorwärts zugewiesene Speicher, der der gesamte derzeit im Socket-Kontingent verfügbare Speicher ist.

sk_wmem_queued ist die Speicherkapazität, die der Socket-Sendepuffer in der Sendewarteschlange belegt und die entweder noch nicht gesendet oder noch nicht bestätigt wurden.

Weitere Informationen zur TCP-Speicherverwaltung finden Sie in Kapitel 9 der TCP / IP-Architektur, -Design und -Implementierung unter Linux. Von Sameer Seth, M. Ajaykumar Venkatesulu


Ich verstehe nicht, wie sich diese Definition von sk_wmem_queuedunterscheidet sk_wmem_alloc. Könnten Sie das etwas näher erläutern? (Wenn Sie die Antwort wissen, können Sie diese Frage gerne beantworten: unix.stackexchange.com/questions/551444/… )
kleiner Typ

1

Siehe die Manpage von ss.

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)

0

In Bezug auf sk_wmem_queuedund habe sk_wmem_allocich die gleiche Frage gestellt, daher werde ich die Antwort hier kopieren:

Ich habe Eric Dumazet, der zum Linux-Netzwerk-Stack beiträgt, eine E-Mail geschickt, und hier ist die Antwort:

sk_wmem_allocVerfolgt die Anzahl der Bytes für SKB, die nach dem Transportstapel in die Warteschlange gestellt wurden : QDISC-Layer- und NIC-TX-Ringpuffer.

Wenn sich 1 MB Daten in der TCP-Schreibwarteschlange befinden, die noch nicht gesendet wurde (cwnd-Limit), sk_wmem_queuesind dies ca. 1 MB , jedoch sk_wmem_allocca. 0 MB

Ein sehr gutes Dokument zum Verständnis der drei Arten von Warteschlangen (Socket-Puffer, Qdisc-Warteschlange und Gerätewarteschlange) ist dieser Artikel (ziemlich lang) . Kurz gesagt, der Socket schiebt die Pakete zunächst direkt in die qdisc-Warteschlange und leitet sie an die Gerätewarteschlange weiter. Wenn die qdisc-Warteschlange voll ist, beginnt der Socket, die Daten in seiner eigenen Schreibwarteschlange zu puffern.

Der Netzwerkstapel platziert Pakete direkt in der Warteschlangendisziplin oder drückt die oberen Schichten (z. B. Socket-Puffer) zurück, wenn die Warteschlange voll ist

Im Grunde genommen: Wird sk_wmem_queuesder Speicher vom Socket Buffer ( sock.sk_write_queue) verwendet, während sk_wmem_allocder Speicher von den Paketen in den Warteschlangen qdisc und device verwendet wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.