LoginSignup
47
23

More than 3 years have passed since last update.

HTTP の Keep-Alive について

Last updated at Posted at 2020-09-03

HTTP の Keep-Alive について確認した時のメモです。

参考

そもそも HTTP の Keep-Alive とは

  • HTTP の Keep-Alive は HTTP の下のレイヤーの TCP/IP 通信を効率化する仕組み
  • Keep-Alive を使わない場合、HTTP のリクエストの都度 TCP/IP の 3way handshake などの TCP/IP の接続開始・終了処理が必要
  • Keep-Alive を使うことで連続したリクエストの時に接続を再利用する
  • HTTPS の場合、下のレイヤーの SSL/TLS を利用し、こちらでも handshake 処理が必要な為、効率化の効果がある
  • HTTP/1.0 ではリクエストヘッダに Connection: Keep-Alive を使いする事で Keep-Alive の利用が出来る。HTTP/1.1 ではデフォルトで利用する
  • クライアントかサーバーが Connection: Close というヘッダーを付与して接続を切るか、タイムアウトするまで接続が維持される

確認してみる

実際に curlhttpd を使って動きを確認してみる
なお、httpd は 2.4 系で確認した

httpd の Keep-Alive は on(デフォルト状態)

httpd 2.4 ではデフォルトで Keep-Alive は on になっている模様

KeepAlive ディレクティブ

念の為確認する
curl [host1] [host2] とリクエストすることで Keep-Alive を使って複数のリクエストを続けて送れるようなのでこれを利用する

$curl http://localhost http://localhost -v
* Rebuilt URL to: http://localhost/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:25:55 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Connection #0 to host localhost left intact
* Rebuilt URL to: http://localhost/
* Found bundle for host localhost: 0x2269c20 [can pipeline]
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:25:55 GMT
< Server: Apache/2.4.43 ()
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Connection #0 to host localhost left intact

最後に Connection #0 to host localhost left intact とあるので2回の HTTP リクエストは都度 TCP/IP の接続は開始・終了せずにやっているように見える。

ただ、よく分からないのでデフォルトで Keep-Alive が有効ではない HTTP/1.0 を使って比較してみる。

$curl http://localhost http://localhost -v --http1.0
* Rebuilt URL to: http://localhost/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.0
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:27:15 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade, close
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Closing connection 0
* Rebuilt URL to: http://localhost/
* Hostname localhost was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#1)
> GET / HTTP/1.0
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:27:15 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade, close
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Closing connection 1

HTTP リクエストの都度 Closing connection 0 及び Closing connection 1 と出力されており、都度 TCP/IP の接続・終了を行っているように見える。
また、HTTP レスポンスについても Connection: Upgrade, close となっており、通信が接続されている事が分かる。

次に HTTP/1.0 を使いつつ、明示的に HTTP リクエストのヘッダに Connection: Keep-Alive を付与しててみる。

$curl http://localhost http://localhost -v --http1.0 -H 'Connection:Keep-Alive'
* Rebuilt URL to: http://localhost/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.0
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
> Connection:Keep-Alive
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:37:43 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade, Keep-Alive
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Keep-Alive: timeout=5, max=100
< Content-Type: text/html; charset=UTF-8
<
Hello
* Connection #0 to host localhost left intact
* Rebuilt URL to: http://localhost/
* Found bundle for host localhost: 0x1742c20 [can pipeline]
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.0
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
> Connection:Keep-Alive
>
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 21:37:43 GMT
< Server: Apache/2.4.43 ()
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Keep-Alive: timeout=5, max=99
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
<
Hello
* Connection #0 to host localhost left intact

この場合、HTTP/1.1 の場合と同じような挙動となり、この場合も HTTP リクエストの都度 TCP/IP の開始・終了は行ってないようにみえる。

httpd の Keep-Alive は off にする

/etc/httpd/conf/httpd.conf に以下を追加する

/etc/httpd/conf/httpd.conf
KeepAlive Off

その後、httpd を再起動してから同じようにリクエストを連続して送る。

$curl http://localhost http://localhost -v
* Rebuilt URL to: http://localhost/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 27 Aug 2020 23:08:38 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade, close
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Closing connection 0
* Rebuilt URL to: http://localhost/
* Hostname localhost was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#1)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 27 Aug 2020 23:08:38 GMT
< Server: Apache/2.4.43 ()
< Upgrade: h2,h2c
< Connection: Upgrade, close
< Last-Modified: Wed, 26 Aug 2020 21:19:15 GMT
< ETag: "6-5adce5f2d1b80"
< Accept-Ranges: bytes
< Content-Length: 6
< Content-Type: text/html; charset=UTF-8
<
Hello
* Closing connection 1

動きとしては HTTP/1.0 と同じ動きとなった。
Keep-Alive が効いておらず、都度 TCP/IP の接続をしているという状況のように見える。

47
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
23