woshidan's loose leaf

ぼんやり勉強しています

Webサーバのkeepaliveとは

久々に書いておいて、めっちゃざっくりした感じででかく出たタイトルだな、と思ったんですが、まぁここloose leafですしね。

この記事では、「keepalive」という言葉が、webサーバの設定でどう言う意味を指すか、みたいなところを確認します。

TL;DR

  • TCP/IPだと1度のリクエストとレスポンスごとにTCPコネクション貼り直す
  • 勿体無いので一回貼ったコネクションは使いまわそう -> keepalive
  • 具体的に言うと、一つのページの中で画像とかの素材を読み込んで… みたいなので細かくリクエストが発生する場合とか効きそう、という想定があるらしい
  • コネクション張っている = リクエストを待ち受ける以外何もしていないスレッドやプロセスがある、ということなのでコネクションをずっと維持していればいいと言うものでもない
  • 1回通信を実行した(=1回分レスポンスを返してから)、どの程度サーバが待ち受けているか、であって、1回分のレスポンスにかけてよい最大時間ではない

今回するkeepaliveってどの辺の話

キープアライブ (keepalive) とは、コンピュータネットワークにおいて、2つの装置間の接続が有効であることを確認し、また、接続が切断されるのを防止するために、装置間で定期的に送信される通信のことである。

キープアライブ - Wikipedia

たとえば、TCPでデータを転送する前にはコネクションを確立する必要があります。

コネクションの確立にあたって、サーバ・クライアントがそれぞれこちらの記事のように状態を遷移させていますが、他方に遷移に伴う通知を行う前に終了した場合など、サーバとクライアントの状態が中途半端なことになってしまうこともあり得ます。

そこで、あらかじめ決められた周期で信号を送信し合うことにして、通信ができる状態か確認するようにしましょうや、という機能が「keepalive」というそうです。

HTTPのヘッダを利用して行う場合と、TCPのパケットに乗っけて行うことがありますが、TCPの方は拡張機能でデフォルトでは無効にされており*1、「keepalive」あるいは「keepalive 設定」といったら、どうもHTTPキープアライブを指すことが多いようです。

で、タグにnginxって入れてるんですが、このHTTP keepaliveはWebサーバのレスポンスに「Connection: Keep-alive」ヘッダを入れてくれって話なので、Webサーバであるnginxとかapacheとかそのレイヤーの設定の話なんでしょうかね。

nginxで利用できるkeepaliveとは

HTTPで喋るWebサーバの話なんで、「HTTP通信をするとき、TCP/IPだと本当は一回ずつコネクションを貼らなければいけないが、キープアライブが有効ならコネクションを張ったままにして、一つのTCPコネクションで複数回「コマンド」と「応答」がやり取りできるようにする」くらいの意味になります。

nginxの場合、

あたりがkeepaliveに関連するディレクティブです。

keepalive_timeout はサーバが一つのクライアントからの接続を何秒くらいオープンにしたままにしておくか、と言う値で、

keepalive_timeout 75s;

のように指定すると、HTTPのレスポンスヘッダに

Connection: keep-alive

と追加されます。長すぎると、もう不要になったコネクションが滞留して、最悪しばらく新しいコネクションが作成できなくなったり、コネクションプールにメモリが食われたりします。0だとkeep alive無効です。

keepalive_requests は keepalive_timeout > 0 の時に有効で、持続的な接続上で許可されるリクエストの数を設定します。

たとえば、nginx でKeepAliveを設定してみる | レンタルサーバー・自宅サーバー設定・構築のヒントからの引用となりますが、

keepalive_requests 100;
keepalive_timeout 75;

の場合は、クライアントから要求がきたら、一度張ったコネクションをそのままに同じクライアントからの再要求を75秒待ちますが、そのコネクションが有効な間に、同じクライアントからの要求が100件を超えたら、待つのを止めます。

一般的な設定で、1ページの必要なリンク先(画像やCSSなど)が、概ね100個を超えないということと、遅くとも75秒以内には、再要求がくるだろう・・・という前提条件のもとの設定 だそうです。

コネクションを張ったままにしているというのは、言い方を変えるとリクエストを待ち受けている(=他のことをしていない)スレッド or プロセスが用意されているということなので、長い or 多ければいいというものではなさそう。

また、わかりにくいのですが、1回通信を実行した(=1回分レスポンスを返してから)、どの程度サーバが待ち受けているか、であって、1回分のレスポンスにかけてよい最大時間ではないみたいです。

現場からは以上です。

参考