Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Персистентные Соединения

Каков HTTP Персистентные Соединения?

HTTP, который персистентные соединения, также названные HTTP, сохраняют - живое повторное использование, или HTTP-соединения, является идеей использовать то же самое соединение TCP, чтобы отправить и получить многократные запросы/ответы HTTP, в противоположность открытию нового для каждой отдельной пары запроса/ответа. Используя персистентные соединения очень важно для улучшения производительности HTTP.

Есть несколько преимуществ использования персистентных соединений, включая:

Преимущества еще более очевидны с HTTPS или HTTP по SSL/TLS. Там, персистентные соединения могут сократить количество дорогостоящего квитирования SSL/TLS, чтобы установить ассоциации по безопасности, в дополнение к начальному установленному соединению TCP.

В HTTP/1.1 персистентные соединения являются поведением по умолчанию любого соединения. Таким образом, если иначе не обозначено, клиент ДОЛЖЕН предположить, что сервер поддержит персистентное соединение, даже после ошибочных ответов от сервера. Однако, протокол предоставляет средства клиенту и серверу, чтобы сигнализировать закрытие соединения TCP.

Что делает соединение допускающим повторное использование?

Так как TCP по его характеру является потоком базируемый протокол, чтобы снова использовать существующее соединение, у протокола HTTP должен быть способ указать на конец предыдущего ответа и начало следующего. Таким образом требуется, что у всех сообщений на соединении ДОЛЖНА быть самоопределенная длина сообщения (то есть, один не определенный закрытием соединения). Сам установление границ достигается или установкой заголовка Длиной до контента, или в случае разделенной на блоки передачи закодированное тело объекта, каждый блок запускается с размера, и концов тела ответа со специальным последним блоком.

Что происходит, если там прокси-серверы являются промежуточными?

Начиная с персистентных соединений применяется к только одному транспортному пути, важно, чтобы прокси-серверы правильно сигнализировали persistent/or-non-persistent соединения отдельно с его клиентами и серверами источника (или к другим прокси-серверам). От клиента HTTP или перспективы сервера, насколько затрагивается соединение персистентности, присутствие или отсутствие прокси-серверов прозрачны.

Что текущий JDK делает для Хранения - Живой?

JDK поддерживает и HTTP/1.1 и HTTP/1.0 персистентные соединения.

Когда приложение заканчивает читать тело ответа или когда приложение вызывает близко () на InputStream возвращенный URLConnection.getInputStream(), обработчик протокола HTTP JDK попытается очистить соединение и в случае успеха, поместить соединение в кэш соединения для повторного использования будущими запросами HTTP.

Поддержка HTTP сохраняет - живой, делается прозрачно. Однако, этим могут управлять системные свойства http.keepAlive, и http.maxConnections, так же как HTTP/1.1 определенный запрос и заголовки ответа.

Системные свойства, которые управляют поведением Хранения - Живой:

http.keepAlive=<boolean>
default: true

Указывает, поддерживают ли (персистентные) соединения, должен поддерживаться.

http.maxConnections=<int>
default: 5

Указывает на максимальное количество соединений на место назначения, чтобы быть поддержанным в любой момент времени

HTTP-заголовок, который влияет на персистентность соединения:

Connection: close

Если заголовок "Соединения" определяется со значением "близко" или в запросе или в полях заголовка ответа, это указывает, что соединение нельзя считать 'персистентным' после того, как текущий запрос/ответ полон.

Текущая реализация не буферизует тело ответа. Что означает, что приложение должно закончить читать тело ответа или вызов близко (), чтобы отказаться от остальной части тела ответа для того соединения, которое будет снова использовано. Кроме того текущая реализация не будет пробовать чтение блока, очищая соединение, означая, не ли целое тело ответа доступно, соединение не будет снова использовано.

Новые функции и возможности у Тигра?

Когда приложение встречается с HTTP 400 или 500 ответов, оно может проигнорировать IOException и затем может выпустить другой запрос HTTP. В этом случае базовое соединение TCP не будет Сохранено - Живым, потому что тело ответа должно все еще там быть использовано, таким образом, сокетное соединение не очищается, поэтому не доступный для повторного использования. То, что должно сделать приложение, вызвать HttpURLConnection.getErrorStream() после ловли IOException , считайте тело ответа, затем закройте поток. Однако, некоторые существующие приложения не делают этого. В результате они не извлекают выгоду из персистентных соединений. Чтобы рассмотреть эту проблему, мы представили обходное решение.

Обходное решение включает буферизацию тела ответа, если ответ> =400, до определенного количества и в пределах ограничения по времени, таким образом освобождая базовое сокетное соединение для повторного использования. Объяснение позади этого - это, когда сервер отвечает a> =400 ошибками (клиентская ошибка или ошибка сервера. Один пример "404: Файл Не Найденная" ошибка), сервер обычно отправляет маленькое тело ответа, чтобы объяснить, кого связаться и что сделать, чтобы восстановиться.

Несколько новых реализаций Sun определенные свойства представляются, чтобы помочь очистить соединения после ошибочного ответа от сервера.

Главный:

sun.net.http.errorstream.enableBuffering=<boolean>
default: false

С вышеупомянутым системным набором свойств к истине (значение по умолчанию является ложью), когда код ответа> =400, обработчик HTTP попытается буферизовать тело ответа. Таким образом освобождая базовое сокетное соединение для повторного использования. Таким образом, даже если приложение не вызывает getErrorStream(), считайте тело ответа, и затем вызовите близко (), базовое сокетное соединение может все еще быть сохранено - живым и снова использованным.

Следующие два системных свойства обеспечивают дальнейшее управление для поведения буферизации потока сообщений об ошибках:

sun.net.http.errorstream.timeout=<int> in millisecond
default: 300 millisecond

sun.net.http.errorstream.bufferSize=<int> in bytes
default: 4096 bytes

Что можно сделать, чтобы помочь с Хранением - Живой?

Не отказывайтесь от соединения, игнорируя тело ответа. Выполнение так может результаты в неактивных соединениях TCP. Это должно быть собрано "мусор", когда на них больше не ссылаются.

Если getInputStream() успешно возвраты, считайте все тело ответа.

Вызывая getInputStream() от HttpURLConnection, если IOException происходит, поймайте исключение и вызов getErrorStream() получить тело ответа (если есть кто-либо).

Чтение тела ответа очищает соединение, даже если Вы не интересуетесь контентом ответа непосредственно. Но если тело ответа длинно, и Вы не интересуетесь остальной частью его после наблюдения начала, можно закрыть InputStream. Но Вы должны знать, что больше данных могло продвинуться. Таким образом соединение не может быть очищено для повторного использования.

Вот пример кода, который подчиняется к вышеупомянутой рекомендации:

try {
        URL a = new URL(args[0]);
        URLConnection urlc = a.openConnection();
        is = conn.getInputStream();
        int ret = 0;
        while ((ret = is.read(buf)) > 0) {
          processBuf(buf);
        }
        // close the inputstream
        is.close();
} catch (IOException e) {
        try {
                respCode = ((HttpURLConnection)conn).getResponseCode();
                es = ((HttpURLConnection)conn).getErrorStream();
                int ret = 0;
                // read the response body
                while ((ret = es.read(buf)) > 0) {
                        processBuf(buf);
                }
                // close the errorstream
                es.close();
        } catch(IOException ex) {
                // deal with the exception
        }
}

Если Вы будете знать заранее это, то Вы не будете интересоваться телом ответа, следует выпустить ГЛАВНЫЙ запрос вместо ПОЛУЧИТЬ запроса. Например, когда Вы только интересуетесь meta информацией веб-ресурса или тестируя на его законность, доступность и недавнюю модификацию. Вот фрагмент кода:

URL a = new URL(args[0]);
URLConnection urlc = a.openConnection();
HttpURLConnection httpc = (HttpURLConnection)urlc;
// only interested in the length of the resource
httpc.setRequestMethod("HEAD");
int len = httpc.getContentLength();

Изменения в Java SE 6

До Java SE 6, если приложение закрывает HTTP InputStream, когда больше чем небольшое количество данных остается быть считанным, тогда соединение должно было быть закрыто вместо того, чтобы быть кэшируемым. Теперь в Java SE 6, поведение должно считать до 512 килобайтов от соединения в фоновом потоке, таким образом позволяя соединение быть снова использованным. Точный объем данных, который может быть считан, конфигурируем через http.KeepAlive.remainingData системное свойство.

Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами