静的ファイルの処理はhttpdに任せる

ロードバランサを置いている時、バックエンドのアプリケーションサーバはなるべくタイトな構成にしたくなるのが人情というもの。 ところが、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側で静的にルーティングするのが前提だったのね。なるほど・・・

[amazon-product]4048702270[/amazon-product]

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