(сетевые сокеты) байты застряли в очереди на 15 минут; Зачем? - PullRequest
4 голосов
/ 02 апреля 2009

У меня есть программа на Java, работающая в Windows (машина Citrix), которая отправляет запрос на серверы приложений Java в Linux; этот диспетчерский механизм все на заказ.

Программа Windows Java (назовем ее W) открывает сокет прослушивания для порта, заданного операционной системой, например, 1234, для получения результатов. Затем он вызывает службу «рассылки» на сервере с «бизнес-запросом». Эта служба разбивает запрос и отправляет его на другие серверы (назовем их S1 ... Sn), и синхронно возвращает клиенту количество заданий.

В моих тестах было 13 заданий, отправленных на несколько серверов, и в течение 2 секунд все серверы завершили обработку своих заданий и пытаются отправить результаты обратно в сокет W.

Я вижу в журналах, что W получено 9 заданий (это число варьируется от теста к тесту). Итак, я пытаюсь найти 4 оставшихся рабочих места. Если я сделаю netstat в этом окне Windows, я вижу, что 4 сокета открыты:

TCP    W:4373       S5:48197  ESTABLISHED
TCP    W:4373       S5:48198  ESTABLISHED
TCP    W:4373       S6:57642  ESTABLISHED
TCP    W:4373       S7:48295  ESTABLISHED

Если я делаю дамп потока W, я вижу 4 потока, пытающихся прочитать данные из этих сокетов, и, очевидно, застрял в java.net.SocketInputStream.socketRead0(Native Method).

Если я войду в каждый из полей S и введу netstat, я вижу, что некоторые байты все еще находятся в очереди на отправку. Это количество байтов не перемещается в течение 15 минут. (Ниже приведено агрегирование netstat с на разных машинах):

Proto Recv-Q Send-Q Local Address               Foreign Addr   State
tcp        0   6385 S1:48197                          W:4373   ESTABLISHED
tcp        0   6005 S1:48198                          W:4373   ESTABLISHED
tcp        0   6868 S6:57642                          W:4373   ESTABLISHED
tcp        0   6787 S7:48295                          W:4373   ESTABLISHED

Если я делаю дамп потока на серверах, я вижу, что потоки также застряли в java.net.SocketInputStream.socketRead0(Native Method). Я ожидал бы написать, но, возможно, они ждут ACK? (Не уверен здесь; будет ли это показываться на Java? Разве это не должно обрабатываться протоколом TCP напрямую?)

Теперь, очень странная вещь: через 15 минут (а это всегда 15 минут) результаты получены, сокеты закрыты, и все продолжается как обычно.

Раньше это всегда работало раньше. Серверы S перемещены в другой центр обработки данных, поэтому W и S больше не находятся в одном центре обработки данных. Кроме того, S находится за брандмауэром. Все порты должны быть авторизованы между S и W (мне сказали). Тайна действительно 15-минутная задержка. Я думал, что это может быть защита от DDOS?

Я не эксперт по сети, поэтому я попросил о помощи, но никто не может мне помочь. Я провел 30 минут с парнем, который захватывал пакеты с помощью Wireshark (ранее Ethereal), но по «соображениям безопасности» я не могу посмотреть на результат. Он должен проанализировать это и вернуться ко мне. Я попросил журналы брандмауэра; та же история.

Я не являюсь пользователем root или администратором этих блоков, теперь я не знаю, что делать ... Я не жду от вас решения, ребята, но некоторые идеи о том, как продвигаться вперед, были бы великолепны! *

Ответы [ 4 ]

3 голосов
/ 02 апреля 2009

Если в вашей локальной сети все работает нормально, то я не предполагаю, что это проблема программирования (см. flush() комментарии).

В противном случае нормальное сетевое соединение между двумя компьютерами? Можете ли вы передавать аналогичные объемы данных через (скажем) FTP без проблем. Можете ли вы повторить эту проблему, собрав воедино клиент-серверный скрипт только для отправки кусков данных соответствующего размера. т. е. хорошее ли сетевое соединение между W и S?

Еще один вопрос. Теперь у вас есть межсетевой экран. Может ли это быть возможным узким местом, которого раньше не было? (хотя я не уверен, что это объясняет постоянную задержку в 15 м).

Последний вопрос. Каковы параметры вашей конфигурации TCP (для W и S - я думаю о параметрах уровня ОС). Есть ли что-нибудь, что могло бы предложить или привести к 15-метровой фигуре.

Не уверен, поможет ли это.

1 голос
/ 03 апреля 2009

Кроме того, что сказал Брайан, вы также можете проверить следующее

1) Запустите tcpdump на любом из серверов и просмотрите последовательность потоков сообщений с момента, когда задание запускается после задержки, когда вся обработка завершена. Это скажет вам, какая сторона вызывает задержку (W или S). Проверьте, нет ли повторных передач, пропущенных подтверждений и т. Д.

2) Есть ли какая-то фрагментация между W и S?

3) Каковы условия загрузки сети на серверах, на которых заблокированы байты? Вызывает ли большая нагрузка выходные ошибки, в результате чего очереди сокетов не очищаются? (Также может быть ошибка NIC, при которой после достижения некоторого условия ошибки буферы NIC не сбрасываются или не могут возобновить передачу, и такое состояние сбрасывается каким-то сторожевым устройством)

Дополнительная информация о двух вышеупомянутых, безусловно, поможет.

1 голос
/ 02 апреля 2009

правый. Если вы используете BufferedOutputStream, вам нужно вызывать flush (), если вы не достигли максимального размера буфера.

0 голосов
/ 04 апреля 2009

Вы уверены , что потоки, застрявшие в вызовах чтения, - это те же потоки, которые отправляли данные? Возможно ли, что фактически задействованные потоки вместо этого блокируются в какой-либо другой деятельности, и ваша стековая нагрузка показывает другие невинные потоки, которые просто выполняют ввод / вывод сокетов? Прошло много времени с тех пор, как я работал с Java, но я смутно помню, как JVM использовала сокеты для IPC.

Я бы осмотрел всю принимающую сторону, чтобы узнать, является ли один из них предполагаемым получателем и вместо этого делает что-то еще в течение 15 минут.

Тот факт, что он работает в одном месте по сравнению с другим, обычно указывает на ошибку синхронизации приложения, а не на проблему центра обработки данных.

...