はじめに
Node.jsは「サーバサイド JavaScript」環境として、近年のブラウザ上で動作するクライアントサイドJavaScriptの盛り上がりに合わせて、急速に注目を集めています。日本においても、Node.js日本ユーザグループ の登録者はすでに800人を超えており、さまざまなブログや技術系サイトで取り上げられたり、雑誌に記事が掲載されたり、実際のサービスで利用が開始されるなど、大きな盛り上がりを見せています。そうした盛り上がりがある一方で、新しく立ち上がった技術に対してよく聞かれる疑問である、「 Node.jsって何?」とか「サーバサイドでJavaScriptが書けるってどういうこと?」といった声も多く聞かれるようになってきました。
そこで第2回目の本記事ではそれらの疑問に答えるべく、Node.jsの過去、現在、そして未来について解説していきます。
Node.js の過去
Node.js の目指しているもの
Node.jsの公式サイト には、「 Nodeの目指すものは、スケールするネットワークプログラムを構築する簡単な方法を提供すること(Node's goal is to provide an easy way to build scalable network programs) 」とあります。つまり、Node.jsは「大量のアクセス」を「簡単かつ高速」に処理できるネットワークプログラミング環境を目指していると言えます。標準ライブラリにHTTPを中心としたネットワークライブラリが含まれているのも、公式サイトのトップページのサンプルコードが簡易HTTPサーバを作るコードであるのも、このゴールを意識しているからに他なりません。
Node.js が生まれた背景、および JavaScript が選択された理由
それではなぜNode.jsが「大量のアクセス」を「簡単かつ高速」に捌くことのできる環境を目指しているのかというと、それはNode.js の開発が開始された2009年頃に遡ります。
その当時、ネットワークトラフィックの急激な増加に伴いC10K問題 が大きくクローズアップされており、大量のコネクションをどのように高速に処理するか、ということについてさまざまな議論が交わされていました。Apacheなどが採用するコネクションごとにスレッドを立ち上げて処理する「スレッドモデル」方式ではマシンリソースを大量に消費してしまい、処理速度の低下やサーバの台数を多くしなくてはいけないなどの問題が発生していました。Node.jsの作者であるRyan Dahl はこの問題を解決するために、NGINXなどが採用している「イベントループ」方式を採用し、その方式に最適化されたプログラミング環境を構築することを決断しました。それがNode.jsです。
「イベントループ」とは簡単に言ってしまえば、シングルスレッドでループ処理をまわし、キューに溜まったイベントを処理していく処理方式です。
このイベントループ方式を採用したプログラミング環境は他の言語でもすでに存在しています。たとえば、RubyのEventMachine やPythonのTwisted などです。ただし、それらの環境には大きな問題が存在しています。それは既存のライブラリがイベントループを意識して作られていないため、既存のライブラリを利用しようとすると途端に処理がブロックしてしまうということです。前述のようにイベントループはシングルスレッドで処理されるので、1つの処理がスレッドをブロックしてしまうと、次のイベントが処理されず、「 少量のリソースで高速に処理できる」というメリットが失われてしまいます。また、それを回避しようとすると、既存のライブラリが利用できないため、新規ライブラリを作成する必要があり、途端にプログラミングが難しくなってしまうと問題がありました。これではNode.jsの目指す「簡単かつ高速」なプログラミング環境を実現できません。イベントループを最大限に活かすためには、すべてがNon-Blockingである必要があるのです。そこで、Ryanはイベントループ、そしてNon-Blockingに適した言語としてJavaScriptを選択する決断をしました。JavaScriptが選択された理由は主に以下の3点です。
マルチスレッドで動作することが前提にない言語であり、イベントループと相性が良かった
標準のI/Oライブラリが存在しなかったため、Non-blocking I/Oを強制するライブラリ群をゼロから自由に構築することができた
Googleが開発している高速なJavaScriptエンジンであるV8 がオープンソースとして公開されており、開発当時(2009年)から実用的な速度で動作させることが可能であった
Node.jsはサーバーサイドでもJavaScriptでプログラミングできることで取り上げられることが多いですが、実はJavaScriptを言語として利用したいという理由で作成されたわけではなく、目的とするプログラミング環境を構築するのにJavaScriptが最適であったからである、というのはとても興味深い事実です。
この辺りの経緯については、Ryan本人が語っている動画 や、@bad_at_math さんの「node.js とは何か 」でより詳しく解説されているので興味のあるかたはご覧になってみてください。
Node.jsの現在
Node.js の普及
「Node.js の過去」では、Node.jsはC10K問題を解決するためイベントループ方式を採用し、Non-blocking I/Oを標準ライブラリとして持ち、 JavaScriptで「大量のアクセス」を「簡単かつ高速」にプログラムすることのできる環境である、ということを説明しました。しかし、ここ最近のNode.jsの普及、爆発的な盛り上がりは、こうした根源的な思想への共感の他に、大きく分けて2つの理由があります。1つは「JavaScript でサーバサイドのプログラムも組める」こと、そしてもう1つが「Socket.IO」です。
JavaScriptでサーバサイドのプログラムも組める
Webに関係するエンジニアならば、JavaScriptは何らかの形で書いたことがあるでしょう。そのため、Node.jsは初期の言語学習コストが低く、心理的な障壁も低いために、ここまで話題を集め、盛り上がりを見せているのではないでしょうか。実際にNode.js日本ユーザグループに参加しているエンジニアの背景もさまざまで、Java、Ruby, Python, Perlなどのサーバサイドエンジニアの方の他に、それまでサーバサイドのコードを書いたことなかったフロントエンジニアの方やデザイナの方なども参加しているのが特徴です。これ以外にも、JavaScriptがプロトタイプベースの非常に強力な言語であること、クライアントとサーバで同じ言語が使えて開発効率が良いこと、JSONベースのデータストアであるMongoDBなどを利用することでデータのインピーダンスミスマッチを考えなくても良いこと、などがNode.jsでプログラミングする魅力となっています。また、既存のクライアントサイドのJavaScriptライブラリが使えることもNode.jsの特徴です。
たとえば、Node.jsでは、jsdomというライブラリを利用することで、jQueryを使ったスクリーンスクレイピングのアプリを以下のように簡単に記述することができます。
// npm モジュール request, jsdom を利用
var request = require('request')
, jsdom = require('jsdom');
// 指定した URL の <title> タグの中身を表示するサンプル
request('http://nodefest.jp', function(error, response, body) {
if (!error && response.statusCode !== 200) {
console.log('Error!');
return false;
}
jsdom.env({
html: body,
scripts: [
'http://code.jquery.com/jquery-1.6.4.min.js'
]
}, function(err, window) {
var $ = window.jQuery;
console.log($('title').html());
});
});
Socket.IO の功績
Socket.IOは、今回の東京Node学園祭 2011 でもスペシャルゲストとして来日するGuillermo Rauch によって開発されたリアルタイム通信モジュールです。ざっくりと説明するなら、WebSocketの機能+αを、スマートフォンを含むほぼすべてのブラウザで動かすことができるモジュールです。以下に公式サイトに載っているサンプルコードを記載しておきます。これだけのコードでブラウザ互換性を気にすることなくリアルタイムなメッセージングが実装できるのは驚きの便利さです。
Server
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
現在、Node.js = リアルタイムWebを簡単に実装できるプログラミング環境、というイメージができ上がってきているのは、Node.jsの高速に多数のアクセスを捌ける素性の良さに加えて、Socket.IOというモジュールが存在したから、といっても過言ではありません。筆者も含めSocket.IOを使いたいからNode.jsを利用している、という意見も数多く聞かれます。ブログなどの記事を見ても「チャットを実装してみた」「 ホワイトボード共有してみた」などの内容で、Node.jsとSocket.IOをセットで取り上げているところも多く、Node.jsの普及にあたってSocket.IOが果たした功績はとても大きいです。
なお、Socket.IOでは本家のサイト の他に、Jxck さんが書いたAPI解説記事 やマニュアルの日本語翻訳 がありますので、ぜひ目を通してみてください。
Node.jsの現状に関するFAQ
「Node.js の現在」の最後の項では、現時点でのNode.jsに関して最近良く聞かれるいくつかの質問と回答を紹介していきます。
Node.jsはどんな風に使うのが便利?
Node.jsは既存の言語やフレームワークを置き換えるものではなく、むしろ相互補完的に利用していくのが良いのではないでしょうか。実際の運用事例でも、Socket.IOを利用して、既存のアプリケーションにチャットやメッセージング、プッシュ通知など「リアルタイム」的を要素を付与する部分に実装に用いたり、多数のアクセスを捌ける特性を利用してAPIサーバとして利用されている事例が多いです。
もちろん、Node.jsでもExpress やSocketStream といったフレームワークを利用して、ある程度の規模なアプリケーションも構築可能ですが、Railsのようのフルスタックのフレームワークの決定版はまだ存在していません。今後の発展に期待しましょう。
既存のライブラリやモジュールはどうやってみつけたらいいの?
npm がデファクトのパッケージ管理ツールとなっていて、コマンドラインツール、またはnpm registry というWebサイトからキーワードで検索ができるようになっています。npmにはすでに1,000個を超えるモジュールが登録されており、ネットワーク、C++バインディングからハードウェア制御まで種々の面白いモジュールが揃っていて、世界中でNode.jsが盛り上がっていることが実感できます。
v0.4系とv0.5系のどちらを使えばよい?
現在、Node.jsは安定板のv0.4系と、開発版のv0.5系が存在します。v0.5系は、Windows対応を目玉とし、Non-blocking I/Oのライブラリがlibev、libeioからlibuv[1] に置き換えられています。2011年9月末現在、Windows版のバイナリは公開されていますが、パッケージ管理ツールであるnpmのバイナリ版が提供されていないことや、既存のネイティブ(C++)モジュールがWindowsでビルドできないものがあるなど、実際の利用はまだ難しいといえます。現時点でNode.jsを使ってみたいという方は、UNIX/Linux/Mac OS X環境でv0.4系を利用することをお勧めします。
ただし、Node.jsは鋭意開発中のプロダクトであり、バージョンがすごい勢いで上がっていきます。インストールする際は、複数バージョンを管理できるツールであるnvm 、またはnave を使ってインストールすることをお勧めします。
[1] libuvは、Non-Blocking I/Oを抽象化するラッパライブラリで、Linux/UNIX環境ではlibev、libeioを利用し、Windows環境ではIOCPをコールするようになっています。libuvは単独でも利用できるため、JavaScript以外の言語(Ruby, Lua, PHP, C#)のバインディングも開発されていることがNode.js公式ブログ で紹介されています。いずれNode.rbとかNode.phpとかNode.csとか出てくるかもしれませんね。
実際に運用されているサービスってあるの?どれくらいの規模の事例があるの?
Node.js作者であるRyanの所属するJoyentはもとより、世界中でさまざまな規模の運用事例が報告されています。現状だと、ゲームなどで利用されるケースが多いようです。まだ詳細は発表できませんが、東京Node学園祭 2011では、講演やライトニングトークで、具体的に日本でのNode.jsの小規模から大規模までの実運用事例を多数紹介していきます。
詳細はわかり次第、公式サイト で発表していきます。お楽しみに。
Node.jsの未来
今後のロードマップ
Node.js の今後のロードマップですが、2011年5月に開催されたnodeconf 2011 の Ryan の基調講演([動画] 、5 Roadmap">[資料] )で、今年中に Windows 対応を目玉とした安定版の Node.js v0.6 がリリースされる予定であることが発表されています。Windows で動くようになることで、開発環境構築の敷居が下がり、より多くの開発者が Node.js に触れられるようになるのではないでしょうか。
Node.js の未来を「東京 Node 学園祭 2011」で聞こう!
v0.6 以降の具体的なロードマップは明かされていませんが、もしかしたら、東京Node学園祭2011にて、作者であるRyan Dahlからその辺りについて新しい発表があるかもしれません。発表の内容については実行委員である私たちもまだ知らないので、東京Node学園祭2011のRyanの基調講演は、今後のNode.jsの未来を知る上でも要チェックです。
Node.jsの未来を直接聞けるかもしれないまたとない機会ですので、皆さま、ぜひ東京Node学園祭 2011にお越しください。
東京Node学園祭2011
http://nodefest.jp/2011/