読者です 読者をやめる 読者になる 読者になる

Memento memo.

Today I Learned.

VegetaでPhoenixとRailsの負荷テスト

以前会社の同期とご飯を食べていた時、 HTTP負荷テストツールのVegetaというものを紹介してもらったので試してみました。

github.com

GitHubのプロジェクトページを開くとイカしたサイヤ人の王子が目に飛び込んできます。

https://camo.githubusercontent.com/417a39e5a142e0877be0a7a6d7a66cb77ea21e8c/687474703a2f2f666330392e64657669616e746172742e6e65742f667334392f692f323030392f3139382f632f632f73736a325f7665676574615f62795f7472756e6b7332342e6a7067

Golang製ツールで、CLIで比較的簡単に扱えるのが特徴のようです。 大量のリクエストを投げるコマンドが vegeta attack です。 大量にエネルギー弾を撃ちまくるイメージですね。 ドラゴンボールの負け確フラグです。 "王子戦法"、またの名を"グミ撃ち"というらしいです。

dic.nicovideo.jp

Vegeta で負荷をかける

とりあえず使ってみます。他所のサーバに負荷をかけると本当に怒られるのでやめましょう。自前で用意したサーバかlocalhostに向かって実行しましょう。

負荷テストの対象は最近ハマってるPhoenix (v1.2.1, Elixir 1.2.6)と、比較用のRails (v5.0.0.1, Ruby 2.2.3)です。

手持ちのMBPのローカルでPhoenixRailsをnewした状態でサーバを立てます。 そしてlocalhostのルートURLに向かってリクエストを飛ばします。

※ 条件は超適当です。

VegetaのREADMEを読みつつ、以下のようなコマンドで rate を変えながら結果グラフを作成してみます。

$ echo "GET http://localhost:3000" | vegeta attack -duration=10s -rate=100 | vegeta report -reporter=plot > rails-100.html

vegeta attack のオプションで以下の内容を指定しています。

  • duration=10s ... 10秒間負荷をかける(今回は全試行で固定値)
  • rate=100 ... 秒間リクエスト数(変動値)

Rails => Phoenixの順で軽く検証してみます。

Rails

※Rails5のデフォルト設定のままPumaを使っています。
チューニングすればもう少しなんとかなるかもしれません。

30req/s

f:id:shotat_jp:20160925171754p:plain

余裕ですね。20ms付近で安定しています。

50req/s

f:id:shotat_jp:20160925171802p:plain

まだまだいけそうです。

80req/s

f:id:shotat_jp:20160925171810p:plain

ダメになりました。 半分くらいの処理が詰まって10秒遅れて処理されてます。(リクエスト受け付けずにVegetaがRetryしてるんでしょうか???HTTPステータスコード等を全く見てないので正確な挙動は不明です。すみません。。。) 通常のレスポンスも70ms程度まで落ち込んでいます。

100req/s

f:id:shotat_jp:20160925171816p:plain

すごいことになりました。

Phoenix

次いでPhoenixです。

30req/s

f:id:shotat_jp:20160925171412p:plain

余裕です。

100req/s

f:id:shotat_jp:20160925171516p:plain

まだまだいけます。Railsはここで死んでました。

500req/s

f:id:shotat_jp:20160925171524p:plain

レイテンシが若干大きくなってますが、概ね100ms以下で捌き切ってます。

800req/s

f:id:shotat_jp:20160925171533p:plain

レイテンシが100ms前後安定してます。

1000req/s

f:id:shotat_jp:20160925171540p:plain

エラーがいろいろ発生し始めました。 最初の2秒くらいは頑張ってますね。

2000req/s

f:id:shotat_jp:20160925171548p:plain

半分くらいエラーになってしまいました。お疲れ様でした。

まとめ

条件は超ざっくりですが、ローカル環境では

くらいいけました。Phoenixの方が10倍くらいパフォーマンス良いみたいな通説があるんですが、大体そんな感じの結果です。

分散環境でもPhoenix + Elixirは強いはずなので、高速で大量のリクエストを捌く必要のあるシステム(ソシャゲやtwitter)に向いてる気がします。通信回数控えめなエンタープライズ系だとメリットより導入コスト・リスクの方が上回るような感覚です。

キャパシティプランニング ― リソースを最大限に活かすサイト分析・予測・配置

キャパシティプランニング ― リソースを最大限に活かすサイト分析・予測・配置

あと、あまり負荷テストとかやったことがないので、 このあたりもう少し勉強していきたいです。 グラフの解釈等間違っていたらご指摘いただけると幸いです。

プログラミングElixir

プログラミングElixir