Структура розетки ядра та TCP_DIAG


18

Я працюю над програмним забезпеченням, яке підключається до сервера даних у режимі реального часу (за допомогою TCP), і у мене відпадають деякі з'єднання. Я здогадуюсь, що клієнти не читають дані, які надходять із сервера, досить швидко. Тому я хотів би стежити за своїми розетками TCP. Для цього я знайшов інструмент "ss".

Цей інструмент дозволяє побачити стан кожного сокета - ось приклад рядка виходу команди 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

Моє запитання: що означає частина пам'яті? Переглядаючи вихідний код інструменту, я виявив, що дані надходять із структури ядра ( sockв sock.h). Точніше, він походить з полів:

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

Хтось знає, що вони означають? Мої здогадки:

  • rmem_alloc : розмір вхідного буфера
  • wmem_alloc : розмір вихідного буфера
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Ось мої розміри буферів:

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

Яка ваша конфігурація розміру буфера? Ви бачите, що буфери прийому насичуються на роз'ємах розетки? Чи припиняє ваш учасник з'єднання на EWOULDBLOCK?
Карлсон

Мої розміри розеток досить малі, я думаю, я оновив пост з ними. Про EWOULDBLOCK я не можу сказати. Мій клієнт знаходиться в JAVA і просто скажіть, що його відключив сервер. Сервер знаходиться на C ++, і це просто говорить про те, що він перервав з'єднання без будь-якої інформації. У мене немає вихідного коду сервера, тому я не можу змінити його поведінку. Здається, що клієнти відключаються, коли вони трохи перевантажені, навіть якщо це триває лише кілька секунд.
Твістер

Чи налаштована конфігурація розмірів буфера на сервері? Чи можете ви дивитися розміри буфера на клієнті? Чи маєте ви доступ до джерела клієнта? Ви запустили netstat -apnc для перегляду розмірів буфера? Ви намагалися збільшити розміри буфера в ядрі, щоб побачити, що відбувається?
Карлсон

Так, вони вже встановлені на максимальне значення сервера (я вважаю, що вони не можуть бути більшими за властивості net.ipv4.tcp_ *, правда?) Для netstat -apnc він не дає мені розмірів буферів, тому я дивився на сс. Щодо ядра, я не корінь на сервері, а ІТ-команди тут досить вперті. Мені потрібно бути впевненим у тому, що відбувається, перш ніж я попрошу їх змінити значення ... І так, я маю доступ до джерела клієнта, і моє розслідування щодо клієнта підтверджує, що відключення відбувається від сервера.
Твістер

netstat -apnc дає загальний розмір черг для надсилання та отримання в Linux. Якщо сервер встановлює буфер максимально доступним, а ви все ще насичуєте, можливо, вам потрібні більш високі настройки буфера на рівні ОС
Карлсон,

Відповіді:


7

sk_forward_alloc - це пам'ять, що розподіляється вперед, яка є загальною пам'яттю, наявної в даний час у квоті сокета.

sk_wmem_queued - це об'єм пам'яті, який використовується буфером передачі сокетів, що знаходиться в черзі в черзі передачі, або або ще не надсилається, або ще не підтверджений.

Ви можете дізнатися більше про управління пам’яттю TCP у розділі 9 архітектури, проектування та впровадження TCP / IP в Linux від Sameer Seth, М. Ajaykumar Venkatesulu


Я не розумію, чим sk_wmem_queuedвідрізняється це визначення sk_wmem_alloc, ви могли б трохи розширити це? (Якщо ви знаєте відповідь, сміливо додайте відповідь на це питання: unix.stackexchange.com/questions/551444/… )
маленький чувак

1

Див. Сторінку чоловіка 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

Щодо sk_wmem_queuedта sk_wmem_alloc, я задав те саме питання, тож я скопію відповідь тут:

Я надіслав електронною поштою Еріку Думазету, який сприяє мережевому стеку Linux, і ось відповідь:

sk_wmem_allocвідстежує кількість байтів для черги skb після транспортного стеку: qdisc шар та кільцеві буфери NIC TX.

Якщо у вас є 1 Мб даних, що знаходяться в черзі запису TCP, ще не надісланої (обмеження cwnd), sk_wmem_queueбуде близько 1 МБ, але sk_wmem_allocбуде приблизно 0

Дуже хороший документ для розуміння того, що ці три види черг (буфер сокетів, черга qdisc та черга пристроїв) - це ця стаття (досить довга) стаття . У двох словах, розетка починається з натискання пакетів прямо на чергу qdisc, яка пересилає їх у чергу пристроїв. Коли черга qdisc заповнена, сокет починає буферизацію даних у власній черзі запису.

мережевий стек розміщує пакети безпосередньо в дисципліні черги або ж відштовхується на верхні шари (наприклад, буфер сокета), якщо черга заповнена

В основному: sk_wmem_queuesчи використовується пам'ять, яка використовується буфером сокета ( sock.sk_write_queue), а sk_wmem_allocпам'ять, яка використовується пакетами в черзі qdisc та пристроїв.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.