ロードバランサを置いている時、バックエンドのアプリケーションサーバはなるべくタイトな構成にしたくなるのが人情というもの。
ところが、unicornだけ走らせているはずのアプリケーションサーバに比べて、フロントエンドのhttpd(nginx)が走っているテスト用サーバの方が何倍も早いという現象が発生した。
条件を色々変えて確かめた結果、意外な結果になった。

とりあえず結論から書くと、unicornだけを走らせてLBから直接叩くのに比べて、間にhttpd(nginx)を挟んだ方が何倍も速い。


ab(apache benchmark)でベンチマークを取って比較してみた結果が以下の通り。
なお、計測対象にはDBのロードもなくビジネスロジックも最小限しかないアクションを選んだ。

unicorn直(クライアント→ロードバランサ→unicorn(TCP))
平均397ms 最大17213ms

nginx経由(クライアント→ロードバランサ→nginx(TCP)→unicorn(sock))
平均65ms 最大300ms

nginxが間に入ると圧倒的に高速になる。(なお、この段階ではnginxにキャッシュはさせていない)
さらにvarnishを挟んでみる。

varnish経由(クライアント→ロードバランサ→varnish(TCP)→nginx(TCP)→unicorn(sock))
平均59ms 最大173ms

うーん・・・静的ファイルならまだしも、動的なコントローラでここまで差が出るとは思わなかった。
nginxは静的なファイルをキャッシュできるので、public以下をキャッシュさせればレスポンスは向上し、unicornも無駄なリクエストを処理しないで済むのでサーバ負荷も減少する。
ここまで考えて気づいたんだけど、Rails3のproduction環境は

config.serve_static_assets = false

がデフォルトになっていて、public以下が自動的にルーティングされないようになっている。
なんでこんな設定になってるんだろうと不思議に思っていたけど、httpd側で静的にルーティングするのが前提だったのね。なるほど・・・

入門と題してるけどだいぶ詳しいです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>