Назад | Перейти на главную страницу

Почему данные попадают в Send-Q? Зависание TCP-сессий

Проблема

Я запускаю IRC-сервер на 20-50 пользователей. Иногда у нас возникают проблемы с тем, что сообщения приходят не вовремя или вообще. После нескольких захватов пакетов мы определили, что сообщения находятся в «Send-Q» сервера. Когда сообщение не приходит, я смотрю на вывод netstat -ct и вижу что-то вроде этого:

Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 1756 ubuntu:ircd 10.8.1.7:63602 ESTABLISHED

Иногда, если я подожду пару минут, Send-Q перейдет в 0 и сообщение будет доставлено, в других случаях время ожидания клиента истекает. Мой вопрос: почему он просто не доставляет сообщения? Что заставляет их так долго сидеть в Send-Q?

sshd также демонстрирует аналогичное поведение, мои сеансы ssh зависают, иногда они возвращаются, иногда они превышают время ожидания.

Задний план

Не уверен, что инфраструктура здесь может быть связана с проблемой, поэтому вот как это выглядит: эти клиенты находятся в Windows 7 и подключаются к OpenVPN. Сервер OpenVPN находится на PFSense, сервер IRC находится в локальной (NAT) LAN, подключенной к PFSense. У меня есть правило брандмауэра, позволяющее клиентам разговаривать с 6667 на сервере.

Расследование ...

Задержка / потеря - выглядит достаточно прилично. Не лучшая ссылка, но я думаю, что это подойдет для IRC и SSH. Вот пинг от моего клиента к серверу, пока мои IRC и SSH периодически зависают:

Ping statistics for 10.8.5.2:
    Packets: Sent = 4478, Received = 4460, Lost = 18 (0% loss)

Приблизительное время приема-передачи в миллисекундах: минимум = 17,2 мс, максимум = 273,4 мс, средний = 32,3 мс

Проблемы с MSS / MTU - MTU вроде в порядке. OpenVPN mtu-test на моем клиенте говорит:

Thu Dec 03 12:41:21 2015 NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[1589,1589] remote->local=[1589,1589]

... а вот мой ручной тест:

> ping -f -l 1472 10.8.5.2

Pinging 10.8.5.2 with 1472 bytes of data:
Reply from 10.8.5.2: bytes=1472 time=23ms TTL=63

> ping -f -l 1473 10.8.5.2

Pinging 10.8.5.2 with 1473 bytes of data:
Packet needs to be fragmented but DF set.

Полоса пропускания / пропускная способность - провел несколько тестов iperf, чтобы убедиться, что нет проблем с пропускной способностью. Опять же, выглядит достаточно прилично:

iperf -c 10.8.5.2
------------------------------------------------------------
Client connecting to 10.8.5.2, TCP port 5001
TCP window size: 63.0 KByte (default)
------------------------------------------------------------
[  3] local 10.8.0.23 port 18587 connected with 10.8.5.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  26.0 MBytes  21.8 Mbits/sec

Спасибо, мы будем очень признательны за любую помощь в понимании «Send-Q» или более конкретные идеи по этой проблеме. Дайте мне знать, если я могу предоставить здесь дополнительную информацию.

Обновить

Выяснилось, что у меня действительно была огромная потеря пакетов. Пинги от client-> VPN этого не показали, но это было очень заметно при использовании fping от VPN-> client. Я заметил, что это были только клиенты Windows, и переустановка новейшего клиента OpenVPN, похоже, устранила потерю. Это могло быть связано с установкой адаптера OpenVPN TAP через создание образа диска. Кажется, что установка его вручную для каждой машины решает проблему.

Данные попадают в очередь отправки, когда приложение записывает их в свой локальный стек TCP ядра. Данные удаляются из очереди отправки, когда TCP-стек другой стороны подтверждает получение данных. Если они находятся в очереди отправки, это означает, что код вашего IRC-сервера отправил их вашему ядру, но другая сторона соединения еще не подтвердила их. Это может быть потому, что они еще не отправлены. Это может быть вызвано ограничениями полосы пропускания сервера или ограничениями производительности сервера, но чаще всего это просто потому, что другая сторона не получает данные так быстро, как сервер отправляет их.