Jetty не закрывает соединение

Я создал простое серверное Java-приложение с помощью Gradle. В качестве встроенного сервера я использую Jetty. Я также использую плагин Gretty, так как он поддерживает последнюю версию Jetty.

Проект работает нормально. И я попытался провести стресс-тест. В рамках моего теста мне нужно проверить время отклика, поэтому я отправляю заголовок "Connection:Close" через curl.

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

ПРИМЕЧАНИЕ :

  1. При отправке заголовка Connection:Keep-alive все нормально
  2. Когда ответ от сервера представляет собой не длинную строку, а более мелкую. Работает нормально (не зависает)
  3. Пробовал стандартный плагин Jetty от gradle, результат тот же.

КАК ПРОВЕРИТЬ:

  1. Соберите и запустите мой проект из консоли ./gradlew appRun
  2. Из консоли bash запустите curl -H "Connection:Close" -i "http://localhost:8080/Environment/example"
  3. Смотрите частичный ответ и соединение все еще живо...

person Ivelius    schedule 06.05.2016    source источник
comment
Как вы думаете, почему вам нужно отправить Connection: close, чтобы проверить время отклика?   -  person user207421    schedule 06.05.2016


Ответы (1)


Похоже, вы путаете режимы постоянного соединения между HTTP/1.0 и HTTP/1.1.

Либо так, либо вы используете очень старую версию curl, которая по умолчанию все еще имеет значение HTTP/1.0.

HTTP/1.0 по умолчанию нет постоянных соединений, поэтому для использования постоянных соединений мы отправляем Connection: keep-alive.

HTTP/1.1 по умолчанию использует постоянные соединения, поэтому, чтобы отключить его, мы можем отправить Connection: close

Использование HTTP/1.0 с Connection: close похоже на отправку этого...

GET /Environment/example HTTP/1.0
Host: localhost:8080
Connection: close

... который создает недопустимое значение заголовка для Connection в соответствии со спецификацией HTTP/1.0

Давайте воспользуемся подробными функциями curl, чтобы увидеть, что на самом деле происходит с подключением...

Пример: HTTP/1.1 при нормальной работе:

$ curl --verbose --http1.1 http://apache.org/ -so /dev/null
*   Trying 88.198.26.2...
* Connected to apache.org (88.198.26.2) port 80 (#0)
> GET / HTTP/1.1
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:05:39 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:05:39 GMT
< Content-Type: text/html
< 
{ [1125 bytes data]
* Connection #0 to host apache.org left intact

Заметили, что он говорит, что он сохранил соединение?

Пример: HTTP/1.1 с ручным Connection: close управлением:

$ curl --verbose --http1.1 --header "Connection: close" http://apache.org/ -so /dev/null
*   Trying 140.211.11.105...
* Connected to apache.org (140.211.11.105) port 80 (#0)
> GET / HTTP/1.1
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> Connection: close
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:06:35 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:06:35 GMT
< Connection: close
< Content-Type: text/html
< 
{ [1106 bytes data]
* Closing connection 0

Ах, заголовки ответа HTTP говорят, что сервер закроется, и curl увидел, что соединение закрыто. Что мы хотели.

Пример: HTTP/1.0 при нормальной работе:

$ curl --verbose --http1.0 http://apache.org/ -so /dev/null
*   Trying 140.211.11.105...
* Connected to apache.org (140.211.11.105) port 80 (#0)
> GET / HTTP/1.0
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:08:27 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:08:27 GMT
< Connection: close
< Content-Type: text/html
< 
{ [4002 bytes data]
* Closing connection 0

Видите, как в заголовках HTTP-ответа говорится, что сервер закроется?

Curl также увидел, что соединение было закрыто.

Это то, что мы ожидаем от нормальной работы HTTP/1.0.

Пример: HTTP/1.0 с постоянным соединением:

$ curl --verbose --http1.0 --header "Connection: keep-alive" http://apache.org/ -so /dev/null
*   Trying 88.198.26.2...
* Connected to apache.org (88.198.26.2) port 80 (#0)
> GET / HTTP/1.0
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> Connection: keep-alive
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:08:37 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:08:37 GMT
< Keep-Alive: timeout=30, max=100
< Connection: Keep-Alive
< Content-Type: text/html
< 
{ [3964 bytes data]
* Connection #0 to host apache.org left intact

Да, сервер указывает, что он также будет использовать Keep-Alive (в соответствии со спецификацией HTTP/1.0), и curl даже соглашается и говорит, что соединение не повреждено.

person Joakim Erdfelt    schedule 06.05.2016