ふ前回の記事に引き続き、サーバー部分のどこが重たいのか、もう少し詳しく調べていきましょう。サーバー内部の様子クライアントとサーバーの間のネットワークを省略して、公式鯖のリクエストが処理される流れを図示したイメージがこちらです。全体を書いても訳が分からないと思いますので、とりあえず、第壱鯖だけに絞って説明します。青い矢印(A)がブラウザがindex.htmlやDodontoF.swfなどの静的コンテンツを読み込むリクエストの流れ。緑の矢印(C)がFlashプラグインが静的コンテンツ(map、キャラクター、カットイン、ダイスなど)を読み込むリクエストの流れ。赤い矢印(B)がチャットデータの送受信などを行う部分で、最も負荷が高い部分です。このうちAとCの処理は、nginxだけでリクエストを返すので、応答時間としてはキャッシュが有効ならA-1の応答時間、キャッシュが無効でもA1とA-2の応答時間の合計となります。赤い矢印の部分は、A-1とB-1とB-2の応答時間の合計となります。Bの処理をさらに細かく見る(CGIとDodontoFServer.rb)B-1とB-2は、レンタルサーバーなどでは、CGIとしてDodontoFServer.rbが動きますが、リクエストの都度、以下のような処理が動きます。公式鯖のようなFastCGIでは、1~3は公式鯖起動時に一度実行されるだけで、リクエストの都度動くのは4だけです。4の部分は常にリクエストが受け付けられるよう各鯖毎に60個のプロセスが常に待機しています。公式鯖が大量人数を処理できる大きな理由がこれです。逆に公式鯖がボトルネックになっている部分もここで、一つの鯖につき60個までしか同時にリクエストを処理することはできません。1回のリクエストを1秒で返したとしても、ログイン人数が120人を超えると応答時間の遅延や再接続が発生します。次に説明するレイテンシの都合により、平均応答時間は0.3~1秒程度を要するめ、1鯖あたり200人超えたあたりから遅いと感じる人が出始めるようです。先ほどの「4.DodontoFServer.rbの処理実行」をさらに分解すると以下のようになります。結果を出力このうち4.2と4.3の部分は、公式鯖内部での処理になりますが4.2はただの構文解析なのでCPUしかほとんど使いません。4.3でsaveDataディレクトリのファイルの読み書きやダイス判定を行うため、CPUとディスクIOを使います。このディスクIOに相当する部分がB-2となりますが、CPUに比べてディスクIOは非常に遅いため、公式鯖では高速化のためにRAMDISKを使っています。そのため、HDDだとランダムIOの平均シークタイム10msec程度、SSDでも1~2msec程度の応答時間を10μsecのオーダーまで短縮させているのです。問題は残りの4.1と4.4で行われる処理です。4.1と4.4のデータ送信は、A-1の通信も含むため、クライアントとの通信に時間がかかると通信待ちが生じてしまいます。それによってCPUやディスクが空いているにも関わらず他のクライアントが待たされてしまい待たされた分のクライアントの応答時間が長くなってしまうのです。レイテンシいろいろではここで、A-1の通信にどれぐらいの時間がかかっているのかレイテンシを調べてみましょう。いろんなところとPINGを打ってパケットの応答時間を調べてみます。50ms厳密には違うので異論は認めますが、応答時間×パケット数が、4.1と4.4のざっくりとした合計時間になります。(やっぱGoogleさんパネェっす。)ICMPのパケットは56byteですしチェックサムの計算や上位アプリケーションレイヤーのハンドシェークにかかる時間も加わるので実際の通信にかかる応答時間はもっと長くなります。過去半年で800,661,712リクエストを、535GBのトラフィックを返しています。いうことは、1リクエストあたりの転送量は、平均して706Byteです。Analogレポートのファイルサイズ毎のグラフで見ても、1KB未満のトラフィックが約90%ですので、妥当な線だと思います。※DNSの名前解決は自分が契約しているISPのDNSやGooglePublicDNSでしょうし、一度解決した後はローカルのキャッシュにより解決されますので、応答時間としてはもうちょっと短くなります。KeepAliveを使えば、リクエストの都度ハンドシェイクをする必要はありませんが、ある理由により公式鯖は無効にしています。仮に自分のPCとどどんとふ公式鯖の間のレイテンシが20msでハンドシェークに20パケットの往復が必要だとすれば、DodontoFServer.rbのデータ通信1回には400ms(0.4秒)を要します。モバイル回線だと、1秒もかかってしまいます。DodontoF.swfからDodontoFServer.rbに更新の有無を確認する頻度は2秒なので、ダイスや他の人の発言は送信されてから画面の表示されるまでの間に0.4~2.4秒の遅れが発生します。1300人が2.4秒間ずつ240個のプロセスを占有するリクエストを2秒毎に出したら、絶対詰まりますよね?サーバーのCPUやディスクIOが暇なのに重いのはそれが理由です。proxyにし、セッションはnginx側で持ったほうがよさそうですね。22:41コメントありがとうございます。本日の投稿で、それに近い解決策を記載いたしました。コメントは受け付けていません。