Подтвердить что ты не робот

Tomcat, HTTP Keep-Alive и Java HttpsUrlConnection

У меня есть два сервера Tomcat, которым необходимо поддерживать постоянное соединение, чтобы сократить связь с SSL-связью. Один сервер (прокси) находится в DMZ, а другой - за другим брандмауэром. Прокси-сервер в основном просто запускает простой сервлет, который выполняет некоторую проверку работоспособности перед отправкой запросов на защищенную машину. По внутреннему запросу машины обмениваются сертификатами перед выполнением реальной работы. Поэтому я хотел бы поддерживать постоянную связь с таймаутом в несколько минут.

Чтобы поговорить с защищенным сервером, сервлет в прокси использует HttpsUrlConnection. Я установил WireShark, и я заметил, что независимо от того, что значение keepAliveTimeout, которое я установил для соединителя на защищенной машине, TCP-соединение закрывается примерно через 5 или 10 секунд. Кажется, что это число соответствует тому, что я прочитал, это тайм-аут по умолчанию и как Java обрабатывает HTTP Keep-Alive. Эта ссылка объясняет, что Java соблюдает тайм-аут Keep-Alive, если он отправляется сервером, в противном случае он использует 5 секунд (прямые подключения) или 10 секунд (прокси-соединения) перед закрытием соединения.

Я пытаюсь выяснить, как заставить Tomcat отправить заголовок Keep-Alive. Не, Connection: Keep-Alive, но Keep-Alive: timeout=x.

Я экспериментировал с HTTP-сервером Apache и изменял keepAliveTimeout в httpd.conf, поэтому заголовок Keep-Alive изменил значение таймаута. Кроме того, Java выполняет этот тайм-аут.

ОБНОВЛЕНИЕ (12/23/11):. После нескольких экспериментов я попытался взломать какой-то быстрый и грязный код, используя Apache HttpClient (3.1), а не HttpsUrlConnection. Похоже, что HttpClient, когда он настроен на использование Keep-Alive, просто ждет завершения соединения с сервером. Я не знаю, как долго он будет ждать. Я снимаю, чтобы поддерживать HTTP-соединение в течение 3 - 5 минут.

4b9b3361

Ответ 1

Я смог использовать HttpClient 3.1, чтобы удерживать HTTP-соединение открытым в течение 5 минут, установив keepAliveTimeout в разъем Tomcat на 300000. Я проверил его с помощью WireShark, что сервер завершит соединение, в то время как HttpClient просто будет ждать. Последующие запросы через HttpClient повторно используют существующее TCP-соединение (избегая дальнейшего подтверждения SSL). Тем не менее, ключ состоит в том, чтобы иметь один экземпляр HttpClient (т.е. Не создавать его каждый раз). Это может быть очевидно для большинства, но я не был уверен, что будет механикой API для HTTPClient. Короче говоря, создайте один экземпляр HttpClient и для каждого запроса (POST, GET и т.д.) Создайте новый PostMethod, GetMethod и т.д. Это приведет к повторному использованию соединения TCP.

Ответ 2

В Tomcat мне удалось установить заголовки в HttpServelet с помощью HttpServletResponse.addHeader() следующим образом:

  response.addHeader("Connection", "Keep-Alive");
  response.addHeader("Keep-Alive", "timeout=60000");

Я подтвердил с помощью WireShark, что это работает с HttpUrlConnection на стороне клиента. Он не работает, если вы не устанавливаете заголовок "Connection", поэтому вам нужно установить оба параметра.

Ответ 3

Java API Http(s)UrlConnection плавно передает информацию Keep-Alive и управляет пулом подключений для каждого хоста сервера в соответствии с после подробного объяснения (читайте внимательно - каждая деталь важна).

В этом случае ваш код должен полностью считывать буферы, закрывать потоки и читать ошибку в случае IOException.

Конечно, у HttpClient меньше ограничений, но лучший способ справиться с вашей ситуацией - использовать MultiThreadedHttpConnectionManager благодаря следующие рекомендации.