Node.jsとは何か、開発者ライアン・ダール氏が語る(前編)~ノンブロッキングとはどういうことか?

2011年5月10日

いま注目されているサーバサイドJavaScriptの火付け役となったNode.js。その開発者であるライアン・ダール(Ryan Dahl)氏自身がNode.jsを紹介した講演「Introduction to Node.js with Ryan Dahl 」のビデオが公開されています

この講演は、サンフランシスコのPHP開発者の集まりであるThe SF PHP Meetup Groupが2月にダール氏を招待して行われたもの。

そのため、Node.jsを知らないデベロッパーに向けて、Node.jsがどのような特徴を持つプログラミング言語なのか、分かりやすく解説しています。内容を紹介しましょう。

Node.jsとPHPとの本質的な違いとは何か

fig

Node.jsを触ってみよう。今日は特にスライドは用意してなくて、タイプしてどんなものかを動かしながら紹介していくつもりだ(注:ダール氏はここで最初に「ノードジェーエス」(Node.js)と言った後は、ずっと「ノード」(Node)で通しています)。

みなさんはダウンロード、してコンパイルすることにあまり慣れていないと思うけれどもNodeはそういったものの1つだ。まだ開発中のものなので、自分でソースからコンパイルしなければならない。

Nodeをダウンロードして、configure、make、make installする。今日はやらないけれども。

fig

NodeにGUIはなく、Pythonのようにコマンドラインで操作する。こうしてプロンプトが出て、ここにJavaScriptを記述できる。

fig

Nodeは、グーグルの頭のいい人たちが開発した、「V8」というChromeにも使われているJavaScriptエンジンの上に構築されている。

このV8の上に多くのライブラリを載せたものがNodeで、ネットワーク処理を得意にしている。もちろん一般的な処理もできるが、ネットワーク処理を適切に行うことに焦点を当てている。

そのため、プログラミングはちょっと変わっている。

まずはその前に簡単な例を出してみよう。足し算をする例を紹介しよう。add関数を定義してadd(1,2)を実行すると、ちゃんと答えが出る。

fig

Nodeにはグローバル変数がある。ブラウザ上でJavaScripを実行するとウィンドウでのグローバル変数があるように、このグローバル変数はサイトに結びついている。

Nodeはブラウザに結びついていないので(ブラウザ上の)ウィンドウオブジェクトはなくて、それがプロセスになっている。このプロセスがグローバル変数になっていて、それがある意味でNodeの中心的存在となっている。

ではエディタを起動して、hello-world.jsを作ってみよう。setTimeoutで、1つ目の引数にコールバック関数、2つ目の引数に待ち時間を設定する。このプログラムがどう動くか想像できるかい?

fig

コマンドラインから実行してみよう。まず“hello”と表示され、2秒待って“world”と表示された。

fig

ここで1つ言えるのは、ブラウザ上でJavaScriptのプログラミングに慣れた人には、Nodeのプログラミングも分かりやすいだろうということ。

同じようなプログラミングをPHPでも作ってみよう。“hello”をプリントして、2秒スリープ、続いて“world”をプリントする(下記の画面の上の3行)。

fig

この2つのプログラムの本質的な違いが分かるだろうか? (会場から「asynchronous」という声が)

PHPの方はsleepし、Nodeの方はtimeoutしている。PHPはsleepで止まってしまう、ここが本質的な違いだ。

Nodeは決して止まらないしスリープしない。Mutex(排他的)なロックも、実行の停止(Halting Execution)もない。アイドルになるだけだ。

この“hello”と“world”の2秒間のtimeoutはビジーループを回しているのではなく、アイドルになっている。CPU利用率はゼロになり、OSはほかの仕事をして、timeoutの時間がくるとプログラムの実行へと戻ってくる。

このサンプルをもう少し変更してみよう。hello-world2.jsを作る。

さっきのsetTimeoutをsetIntervalに変えよう。すると、“hello”を表示したあとで2秒ごとに“world”“world”“world”と連続で表示されるだろう。

fig

実行してみよう。たしかにそうなる。

fig

いま、会場からいい質問があった。最初のスクリプトは実行後終了してプロンプトに戻った。しかし2番目のスクリプトは終了せず動作し続け、プロンプトには戻らない。なぜか?

これはNodeの大事な一面を示している。

これはコールバックがネットワークコネクションなりインターバルタイマーなりの呼び出しをずっと待っていことができる、ということなのだ。

並列処理を実際に試してみる

ここまではJavaScriptをコンソールから試してきた。次は、Webサーバの例を見てみよう。Hello WorldのHTTPバージョンだ。

httpモジュールをロードしてHTTPサーバを作る。ここにコールバックを入れると、リクエストがくるたびにそれが実行される。

fig

このサーバを「s」として、これにポートをバインドする。

ここに200のOKステータスをヘッダで返すようにする。そして“hello world”をボディとして返すようにする。

fig

ではこれを実行してみよう。まだ何も起こらない。ポートをlistenしている状態だ。

fig

curlでローカルホストを読んでみる。すると“hello world”が戻ってきた。うまくいった。

fig

Webブラウザからも“hello world”がちゃんと帰ってくる。エクセレント。

fig

ヘッダをチェックしてみよう。こうなっている。

fig

content-typeは「text/plain」になっていて、それ以外に2つのヘッダがある。Connectionが「keep-alive」になっているのはなぜだろう? モダンなHTTPではパーシステントなコネクションができるようになっているからだ。

ではTransfer-Encodingが「chunked」になっているのは? そう、ストリーミングだ。

さっきのスクリプトを書き換えて、途中にsetTimeoutを入れてみよう。何が起こるだろうか?

fig

動かしてみよう。“hello”と表示され、2秒あいてから“world”が表示される。

これは1つのリクエストに対して、“hello”から“world”まで1つのボディとして返している。これがTransfer-Encodingが「chunked」になっているということだ。

例えば、HTTPのヘッダを返した段階では、ボディがどれくらいの大きさなのか分からない。MySQLからの何百件もの検索結果が含まれているのかもしれない。

そういう場合、サーバ側ですべての結果をバッファリングするような複雑なことはしたくない。MySQLが結果を返したら、それをそのままクライアントに渡すほうがいい。HTTP 1.1ではコネクションを維持したまま複数のレスポンスを返せる。

細かい話はここまでにしておこう。

言いたかったのは、Nodeでは“hello”から“world”のあいだの2秒間もサーバは立ち上がっていて、スリープしているのではなくアイドルになっていて、ほかのコネクションを扱うことができるようになっている、ということだ。

例えば、Apache Bench(abコマンド)で、いまのサーバに対して100回のリクエストを送ってみよう。もしも頭の悪いサーバならば、2秒後に1つ目のリクエストが終わり、4秒後に2つ目のリクエストが終わり、6秒後に3つ目のリクエストが終わる。もしもsleepで2秒待つようになっていればそういうことだ。

しかし、このサーバはアイドル状態になってほかのコネクションを扱うことができる。実際にやってみよう。100のリクエストを並列性100で実行してみる。

fig

100回テストを繰り返してかかった時間は2.026秒だ。

fig

つまり、Nodeは並列性をうまく扱うことができる、決してHaltもsleepもせず、つねにコネクションをうまくハンドルできることができる、ということを示せた。

(続きは後編、「Node.jsとは何か、開発者ライアン・ダール氏が語る(後編)~ 複数コネクションの並列処理とデバッグ」へ) 。

このエントリーをはてなブックマークに追加
follow us in feedly

タグ : JavaScript , Node.js , システム開発



≫次の記事
Node.jsとは何か、開発者ライアン・ダール氏が語る(後編)~ 複数コネクションの並列処理とデバッグ
≪前の記事
次世代JavaScriptを“いま”実現するグーグルの「Traceur」

Loading...

Blogger in Chief

photo of jniino Junichi Niino(jniino)
IT系の雑誌編集者、オンラインメディア発行人を経て独立。新しいオンラインメディアの可能性を追求しています。
詳しいプロフィール


Publickeyの新着情報をチェックしませんか?
Twitterで : @Publickey
Facebookで : Publickeyのページ
RSSリーダーで : Feed



Publickey 最新記事 10本

Publickey Topics 最新記事 10本


PR - Books


fig

fig

fig

fig



blog comments powered by Disqus