ちょいと前にツイートしたこの件のまとめ。新規サービスのリリースや既存サービスに新しい機能が追加される際に、しばしばそのソースコードを確認しているのですが、僕がどんなところを見ているのかまとめてみました。

そのサービスへの導線とランディングページの確認

どんな素敵なサービスも、機能も適切な誘導がなければ使われる事はありません。また誘導次第では大量のアクセスが一度にサーバに対してやってきます。まず確認するのは新しいサービスへの導線やランディングページで、どのページに最もアクセスがくるかということです。

リリース前という限られた時間で、全てのソースコードに目を通すことは難しいので、この最もアクセスであろうページ、1つ2つに確認対象を絞ってしまいます

コントローラのコードの調査と外部との通信の洗い出し

アクセスの多いページを確認したら、ソースコードの中でコントローラのコードを探します。最近の弊社ではWebアプリケーションフレームワークとしてAmon2の採用が増えているので見当が付けやすくて助かります。

コントローラのコードを見つけたら、そこから処理をさかのぼりながら、外部と通信を行う箇所を洗い出します。MySQL、memcached、その他データベース、外部APIなどがその対象です。多くのWebアプリケーションの場合、外部との通信を行っている箇所が性能のボトルネックとなるためです

データベースとの接続・切断のタイミング

データベースというとすぐにSQLの話になってしまいますが、その前にアプリケーションからどのようにデータベースへ接続しているのかを確認します。TCPのハンドシェイクのコストはそれなり高いので、適切な範囲で接続を維持するようにして効率性をあげます。イベントベースで動くmemcachedはコネクション維持のコストが小さいのでできるだけ長いプロセス単位での接続、MySQLは1コネクション1スレッドと少しコストがあがるのでリクエスト単位で接続を落とすようにしています

データベースの構成と参照先

ほとんどのサービスの初期のMySQLの構成は、Master:Slave=1:1になっています。この構成でSlaveを参照してしまうと、可用性が下がるなど運用に大きな問題がでます

MySQLをmaster:slave=1:1構成にして参照をslaveに向けるのがなぜ良くないか
http://d.hatena.ne.jp/sfujiwara/20110620/1308531677

slaveという名前のサーバがあると、つい参照してしまいがちですが、そこは我慢して使わないようにしましょう

キャッシュの使い方

MySQLのチューニング、適切なスキーマ設計、 SQLのチューニングももちろん重要なのですが、アクセスが集中する場所ではMySQLを使わず、memcachedやサーバのDiskにキャッシュを作って利用するのが常套手段です。

その際に気をつけるのがキャッシュが切れた時の動作、キャッシュが切れた瞬間にアプリケーションサーバからデータベースに一斉にアクセスが飛び、過負荷に陥ってしまうことです。リリース前の時間のない時でもキャッシュが切れる前にcronでアップデートするなのどの手段はとれると思われます。

またISUCON2で優勝組の5倍の性能を出す方法でも用いた、バッチで静的なHTMLに書き出し、アプリケーションサーバで処理しないという手もあります。ついついアプリケーションで処理することだけを考えてしまいますが、一歩下がった視野を持てるようになりたいものです。

アプリケーションサーバのプロセス数/プロセス生存期限

これはソースコードではないですが、本番サーバにデプロイされたあとのアプリケーションサーバのプロセス数やApacheでいうところのMaxRequestPerChildの設定値も確認します。

Perlでよく使われるStarmanStarletというpreforkなアプリケーションサーバのデフォルト値は以下のようになっています

サーバ名 MacClient(プロセス数) MaxRequestPerChild(プロセス生存期限)
Starman 5 1000
Starlet 10 100

プロセス数が適切か、生存期限が短すぎないかあたりを確認します。またStarletでは—max-reqs-per-childと—min-reqs-per-childオプションが用意され、プロセスの生成と終了のタイミングにランダム性を取り入れる事ができます。

その他/モニタリング準備

Perlのアプリケーション限定な話になってしまいますが、前のエントリーで紹介したPlack::Middleware::ReverseProxyのロード順も確認しています。

またリリース後はアプリケーションサーバのプロセスのモニタリングを行うためPlack::Middleware::ServerStatus::Liteは必ず導入をお願いしています。他の言語だとなにがあるんだろ。

まとめ

以上、こんなところを僕は見るようにしていますが、確認してきちんと見たつもりでもリリースしてふたを開けてみたら、予想以上のアクセスがあったり見逃していたバグがあったりと問題はでます。そういう時はテンション上げて問題解決に取り組みます。ヒャッハー!

参考文献

松信さんのデータベース本

Mobageのサーバサイドアプリケーションチューニングは参考になるところが多い

Perlの連載がfujiwaraさんの記事Webアプリケーションのパフォーマンス改善に関する記事です

もうひとつWeb+DB PRESSから、Vol.70のRailsアプリケーションの高速化の記事も参考となるでしょう

このブログ記事について

このページは、Masahiro Naganoが2012年12月 7日 16:46に書いたブログ記事です。

ひとつ前のブログ記事は「Plack::Middleware::ReverseProxy はIPアドレスを利用する他のミドルウェアより先に指定しましょう!」です。

次のブログ記事は「Apache HTTP ServerをRFC6585の"429 Too Many Requests"に(とりあえず)対応させるパッチ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja