HTTPのkeepaliveの仕様を勘違い

Pocket
LinkedIn にシェア

HTTPのkeepaliveという機能は非常に有名と思いますが、自分はあまり深くは知らずにいました。

しかし、ちょうどそのkeepaliveを使った部分で性能問題にぶつかり、仕様を詳しく調べてみて勘違いしていることが発覚したのでメモします。

少し古いですけど、以下が仕様のドラフトっぽかたったので読んでみました。
http://tools.ietf.org/id/draft-thomson-hybi-http-timeout-01.html

主に重要な部分は、パラメータで、以下がある。

  • timeout
  • max

それぞれ、そのままDBなどのコネクションをイメージして勝手に思い込んでいましたが、よく読むと「max」の概念がぜんぜん違うことに気づきました…。

引用すると、以下のとおり。

まず、timetou(タイムアウト)。

こちらは、思っていたとおり、確立した接続が利用されない場合ににコネクションを保っている時間を表す。
よく言われるのは、HTTPのページ一つを送るのに必要な時間を少し超えたくらいをタイムアウト値に設定する、というもの。

問題のmaxは、「サーバあたりの接続確立最大数」ではなく「接続あたりの最大リクエスト数」であった、という勘違い。

確かに、そうかいてありますね…。

このとき思ったのは、今回出ている課題はこのkeepaliveの弱い部分にぶち当たったのでは?ということ。

つまり、ラッシュをかけたとき、

  1. サーバ側で最大リクエスト数に達した接続を切ろうとする
  2. クライアント側でサーバで切ろうとされている接続を使ってリクエストを送ってしまった
  3. サーバ側はリクエストを受け取れずに処理されない
  4. クライアントはkeepaliveのtimeoutだけ待ってリクエストを失敗とみなす

となって、かなりのラッシュをかけたときにリクエスト詰まりが発生して結局TPSが出ない、という問題があらわれるわけではないかということです(未検証)。

とはいうものの、このkeepaliveとhttpリクエスト自体が、現在主流とされているhttpリクエストを使った通信(SOAP通信などのAPI通信)を想定していないせいと思います。

こういう場合は逆にkeepaliveしないほうがよいような気がします。

なんでもかんでもkeepaliveしちゃいけないのかもしれないですね。

あと、仕様はきちんと確認しなきゃいけないですね…。

 

(2014/10/7追記)

keepaliveを全て切ってラッシュしたところすごくスムーズにリクエストがさばけました。TPSもいい感じに出ます。

やっぱり、keepaliveの仕様が想定した使い方をしていないからですかね。keepaliveはHTTPのwebページには設定すべきでしょうが、それ以外は性能が出るか確認して設定すべきですね。