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

Причины сценария тайм-аута TCP

На самом деле в настоящее время я изучаю длительные соединения веб-приложения на основе Java / Tomcat. После исключения каких-либо внутренних или прикладных причин я перехожу к сетевому уровню. Причина, по которой я исследую эту проблему, заключается в том, что у нас, казалось бы, случаются случайные всплески в нашем мониторинге времени отклика. Во время расследования я обнаружил, что это поведение вовсе не случайное, а запускается определенными клиентскими HTTP-запросами. Особенностью этих подключений является то, что все они происходят с одного и того же IP-адреса и, похоже, используют прокси Bluecoat, потому что я вижу HTTP-заголовок x-bluecoat-via.

Как я уже сказал, само приложение работает нормально, только конец соединения (с точки зрения Tomcat) как-то задерживается. Сервер не общается напрямую с клиентом, а находится за балансировщиком нагрузки F5, который должен фактически кэшировать ответы (чего может не происходить из-за заголовка идентификатора accept-encoding и фактического размера ответа для буфера).

Я получил дамп TCP, из-за досадной ошибки в настоящее время я вижу только пакеты из LB на сервер приложений, а не фактические пакеты, отправленные с сервера приложений.

Дамп содержит несколько запросов к одному и тому же TCP / IP-соединению, что связано с пулом соединений, выполняемым F5. Последний HTTP-запрос к этому соединению - это фактическое соединение, которое в нашем журнале было отмечено как продолжительное (925836.442 мс). Я вижу пакеты запросов, серию ACK, которая заставляет меня поверить, что сервер приложений пишет свой ответ, а затем, наконец, два пакета FIN, ACK, за которыми следуют RST, ACK, который является последним пакетом, отправленным F5.

С точки зрения времени все это происходит в течение 250 мс, последний пакет отправляется за 15 минут и 13 секунд, прежде чем я увижу журнал ответов на сервере приложений, который записывается после того, как Tomcat считает, что ответ завершен.

На данный момент у меня вроде как нет идей, и у меня есть несколько открытых вопросов:

Есть ли какая-либо причина, по которой Linux будет поддерживать соединение, которое получило RST, и не сообщать об этом на уровне приложения?

Есть ли другой тайм-аут, который может привести к такому поведению? Если бы это был тайм-аут повторной передачи TCP, я бы увидел больше RST от LB.

Любая другая идея, почему закрытое соединение на проводе приведет к все еще открытому соединению на уровне приложения?

Как то, что происходит на уровне приложения (специальный HTTP-запрос), может привести к воспроизводимому поведению на транспортном уровне?

Может быть, я совершенно ошибаюсь, и это проблема сохранения соединения внутри Tomcat?

Я действительно не могу помочь на сетевом уровне, но на Tomcat есть несколько мест, где вы можете настроить это http://tomcat.apache.org/connectors-doc/reference/workers.html . Вы можете попытаться перезаписать тайм-аут и настроить его так, чтобы соединение было закрыто через определенное время.

По ссылке у вас также есть конфигурации балансировщика нагрузки, которые могут быть полезны в вашем сценарии.