Структура сокета ядра и 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 ++, и он просто говорит, что он сбросил соединение без какой-либо информации. У меня нет исходного кода сервера, поэтому я не могу изменить его поведение. Кажется, что клиенты отключаются, когда они немного перегружены, даже если это длится всего несколько секунд.
— Twister

Настраивается ли конфигурация размеров буфера на сервере? Можете ли вы смотреть размеры буфера на клиенте? У вас есть доступ к источнику клиента? Вы запускаете netstat -apnc для просмотра размеров буфера? Вы пытались увеличить размеры буфера в ядре, чтобы увидеть, что происходит?
— Карлсон

Да, они есть и уже настроены на максимальное значение сервера (я думаю, они не могут быть больше, чем свойства net.ipv4.tcp_ *, верно?) Для netstat -apnc это не дает мне размеры буферов, вот почему я посмотрел на сс. Что касается ядра, я не являюсь пользователем root на сервере, и ИТ-команды здесь довольно упрямы. Мне нужно быть уверенным в том, что происходит, прежде чем я попрошу их изменить значения ... И да, у меня есть доступ к клиентскому источнику, и мои исследования на клиенте подтверждают, что отключение происходит с сервера.
— Twister

netstat -apnc дает вам общий размер очередей отправки и получения в Linux. Если сервер устанавливает максимальный доступный буфер и вы все еще насыщаете, может быть, вам нужны более высокие настройки буфера на уровне ОС
— Карлсон

Ответы:


7

sk_forward_alloc это выделенная в прямом направлении память, которая является общим объемом памяти, доступной в настоящее время в квоте сокета.

sk_wmem_queued это объем памяти, используемый буфером отправки сокета, поставленным в очередь в очереди на передачу и либо еще не отправленный, либо еще не подтвержденный.

Вы можете узнать больше об управлении памятью TCP в главе 9 « Архитектура TCP / IP, проектирование и реализация в Linux». Самер Сет, М. Аджайкумар Венкатесулу


Я не понимаю, чем 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 и кольцевые буферы TIC NIC.

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

Очень хорошая статья для понимания того, что представляют собой эти три типа очередей (буфер сокетов, очередь qdisc и очередь устройств), является этой (довольно длинной) статьей . Короче говоря, сокет начинает с отправки пакетов непосредственно в очередь qdisc, которая перенаправляет их в очередь устройств. Когда очередь qdisc заполнена, сокет начинает буферизовать данные в своей собственной очереди записи.

сетевой стек помещает пакеты непосредственно в дисциплину очередей или возвращает обратно на верхние уровни (например, буфер сокетов), если очередь заполнена

Итак, в основном: sk_wmem_queuesпамять, используемая сокетом buffer ( sock.sk_write_queue), а sk_wmem_allocпамять, используемая пакетами в очередях qdisc и device.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.