廣川です。
サーバサイドJavascriptとNodeについてまとめました。
サーバサイドJavascriptとは、クライアント側でなくサーバ側で動くJavascriptのこと。
IISは標準でjscriptというJavascriptの拡張言語に対応している。
他にも、apacheモジュールの「mod_js」や、aptanaの「Jaxer」等がある。サーバサイドJavascriptの標準規格を決めようとする動き「CommonJS(元はServerJS)」もあるようだ。
Javascriptはクライアント(ブラウザ)で動かす言語というイメージしかなかったのだが、予想以上に使える場面は広い。JavaSE6の標準機能にはJavascriptを実行するためのクラスもある。
その中で、最近話題性が上がっているのが「Node」というサーバサイドJavascript。
Nodeは、Google Chromeに搭載されたJavascriptの実行エンジン「V8」を利用して作られている。
サーバサイドJavascriptは色々あるが、Nodeにおける特徴としては以下が挙げられる。
- イベントループモデル
- ノンブロッキングI/O
これらは、とにかく「多くのアクセスを捌くため」に採られている方式である。
現在のサーバのアーキテクチャにはC10K問題という問題がある。クライアントからの同時接続数が10K(=1万)を超えると、ハードに問題は無くとも、重くなってしまうという現象だ(ただし1万が上限ではなく、五桁がボーダーという意味でつけられているようだ)。
この問題を解消するために、Nodeでは以上二点の方式が取り入れられている。
では「イベントループモデル」と「ノンブロッキングI/O」とはどのような方式なのか。
イベントループモデルの対義語となるのは「スレッドモデル」。Apache等のサーバに見られる標準的な処理方式だ。
スレッドモデルは1つのクライアントに対し1~Nスレッドを生成する。つまり5台から接続されれば5以上のスレッドで対応することになり、その分メモリなどのリソースを用意する必要がある。
イベントループモデルはというと、5台のPCから接続されたとしても、1つのプロセスで処理をこなす。そのためメモリを食い尽くすことがない。数あるライブラリの中には複数のプロセスを同時に動かし、バランサの役割を果たすものもあるようだが、基本はシングルプロセスである。
ノンブロッキングI/Oの対義語となるのは「ブロッキングI/O」。
ブロッキングI/Oは、例えばファイルアクセスを行った時、ファイルが最後まで読み込まれるまでは後続処理を待機させるという方式だ。
逆にノンブロッキングI/Oは、ファイルを全て読み込まずとも後続処理は待機させず、次の処理を始める。
つまり「イベントループモデル」かつ「ノンブロッキングI/O」ということは、
- A→Bの順でリクエストがあった
- Aの処理を開始する
- Aの処理中にXにアクセスする必要があった
- Xの読み込みが最後まで終わるまで、Bの処理を始める
- Bの処理中にXの読み込みが終わった
- Bの処理を中断し、Aの処理に戻る
- Aの処理を終える
- Bの処理を再開する
という処理順序になる。
「スレッドモデル」かつ「ブロッキングI/O」の場合は、
- A→Bの順でリクエストがあった
- 1.スレッド1がAの処理を開始する
- スレッド2がBの処理を開始する
- スレッド1がAの処理で必要なXの読み込みを開始する
Xの読み込みが終わるまでスレッド1は待機する - スレッド2がBの処理で必要なXの読み込みを開始する
Xの読み込みが終わるまでスレッド2は待機する - スレッド1がXの読み込みを終え、Aの処理を続行する
- スレッド2がXの読み込みを終え、Bの処理を続行する
- スレッド1がAの処理結果を返す
- スレッド2がBの処理結果を返す
という処理順序になる。
AやBの処理がI/Oアクセスをせず、なおかつ膨大なコスト(時間)がかかるものであれば、「イベントループモデル」「ノンブロッキングI/O」は効果を発揮しない。
つまり、Nodeをより効果的に活用するには、
- 何かしらのI/O処理を行う
- I/O以外の処理が簡素でコストがかからない
といったアプリケーションを構築する必要がある。