インターネットのサービスは、アクセスしてきたユーザーを「待たせない」ことが大前提だ。「待たせない」サービスを実現するために、新しいインフラ技術が次々と登場している。例えばJavaScriptの実行基盤を構築するサーバー用ソフト「Node.js」もその一つ。大量の同時接続ユーザーに対して高速にレスポンスできる技術として、今、大きな注目を集めている。

 Node.jsは、Webサーバー構築ソフト「Apache」やWebアプリケーションサーバー構築ソフト「Tomcat」などと置き換えて使う。ただし、単純に置き換えるだけで必ずレスポンスが高速になるわけではない。Node.jsが持つ本来のパフォーマンスを引き出すには、実装するWebアプリケーションの開発に注意が求められる。

“ループ”を止めないアプリが不可欠

 Apacheの場合、複数のスレッドを起動して並行処理することで、大量のアクセスに対応できるようにしている。ただし、起動するスレッドが多くなるほど消費するCPUやメモリーなどのリソースが増えるため、パフォーマンスは低下しやすい。このため起動可能なスレッドの数をあらかじめ設定しておくことが多いが、そうなると、今度は空きスレッドが出るまでリクエストを受け付けられなくなる。

 Node.jsは、シングルスレッドでしか動作しない。大量のアクセスに対しては、とにかくリクエストを受け付けてしまう。だが、シングルスレッドなので一つひとつのリクエストを高速に処理していかないと、処理すべきリクエストは増える一方となる。シングルスレッドでも高速に処理するため、Node.jsは「イベントループ方式」と「非同期I/O処理」を実装している。

 イベントループ方式は、I/O処理を監視しながらプログラムを実行する方式である。I/O処理とは、ファイルの読み書きやデータベースへのアクセスといった処理のことで、OS側で実行される。例えばファイルの読み込みであれば、プログラムがOSに読み込み処理を依頼し、読み込みが完了するとOSがプログラムに通知する。

 I/O処理が「同期」の場合、プログラムは依頼したI/O処理が完了するまで、次のステップに進まずに待ち続ける。Apacheは同期I/O処理で対応している。リクエストごとにスレッドを割り当てて処理しているため、依頼したI/O処理の完了を待たないと正しい処理結果をレスポンスできないからである。

 これが「非同期」になると、プログラムは依頼したI/O処理かどうかにかかわらず、とにかくI/O処理が完了したものから順番に実行結果を受け取り、次のステップに進む。この非同期I/O処理をイベントループに組み込むと、処理の開始は受け付けたリクエストの順番通りになるが、レスポンスは処理が終わった順番に返されるようになる。