Структура сокета ядра и 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.