ページの先頭です


ページ内移動用のリンクです

  1. ホーム
  2. IIJの技術
  3. IIJ Technical Seminar
  4. 技術情報(2011年~2015年)
  5. 注目のサーバサイドJavaScript実行環境「Node.js」

注目のサーバサイドJavaScript実行環境「Node.js」

2012年7月31日

今、ソフトウェア開発者の中で注目されている「Node.js」。本記事の前半は、Node.jsが誕生した背景とこれまでの歩みといった概要について紹介します。後半では、Node.jsのアーキテクチャの概要や今後の課題や展望など技術的な内容について説明します。なお、Node.jsの正式名称はNodeです。他と区別したい時にNode.jsと呼ぶことになっていますが、ここでは初めてNode.jsを知る方にもわかりやすいよう記載名をNode.jsで統一します。

Node.jsが生まれるまで

1995年に誕生したJavaScriptは、ブラウザ上で動作するスクリプト言語として開発されました。当初はJavaScriptの実行速度も遅く、セキュリティの問題も数多く発生したため、ブラウザのJavaScriptの機能をオフにすることが一般的に推奨されていた時期もありました。その後、個人向けサービスを中心に多様なWebサービスが立ち上がり、ブラウザの高性能化・高機能化やjQueryなどの汎用ライブラリの登場によって、JavaScriptの技術環境は近年格段に進歩しました。特にGoogle Chromeに搭載されているJavaScriptエンジン「V8」は、ブラウザのJavaScriptの実行性能に劇的な向上をもたらす原動力になったと言えるでしょう。

一方、インターネットではソーシャルとモバイルを対象にしたサービスが数多く台頭し、以前より多数のユーザが同時にリアルタイムでデータ交換するシステムの開発が求められるようになりました。従来のLAMP(Linux/Apache/MySQL/PHP)構成のシステムではこのようなサービスの要求を実現しようとすると、性能確保のために非常に多くのハードウェアリソースが必要となります(これは、C10K問題blankと呼ばれています)。

この問題を克服するため、libeventblankやlibev/libeioといったイベント駆動でI/Oをハンドリングするライブラリが開発され、それらを活用したnginxやmemcachedなどの高性能アプリケーションが登場してきました。

Node.jsの誕生とこれまでの歩み

このような時代背景のもと、2009年にNode.jsは誕生しました。Node.jsのクリエイターRyan Dahl氏は、上述のJavaScriptエンジンV8とイベントループライブラリ(libev/libeio)の2つを組み合わせてサーバ上で動作するJavaScript実行環境を作成しました。その目的を、

「Nodeのゴールは、ノンブロッキングなネットワークプログラミングをサーバ開発に熟知していないユーザにも可能にすること」

と定めています。通常、プログラムがネットワーク経由のデータの送受信やファイルの入出力などのI/O操作を行うと、操作が完了するまで「待ち」時間が発生します。ノンブロッキングとは、このI/O操作の待ち時間が発生してもプログラム自体の動作が待たされることがなく、直ちに次のプログラムの動作に進めることを指します。Node.jsは、このようなサーバプログラム上で発生する様々な「待ち」を解消する仕組み(非同期I/O処理)を整えることによって、大量な接続を高速に処理することを実現したのです。これまでもサーバサイドで動作するJavaScriptは存在していましたが、上述した非同期I/O技術とJavaScript技術の成熟を受け、Node.jsは現在に求められるサービス特性に合ったタイミングでの登場であったと言えます。

開発者の視点では、Node.jsは基本的にシングルプロセス・シングルスレッドで動作するため、 CやJavaを使ったときのような複雑なマルチスレッドプログラミングを行う知識を必要としません。開発者は、通常のブラウザ上でプログラミングを行う感覚でアプリケーションの開発が行えます。また、npm(node package manager)というパッケージ管理機能でサードパティのモジュールを作成・公開・導入できる仕組みが整っているため、ユーザが容易に機能の拡張ができるのも特徴です。Node.jsがオープンソースとして公開されると、興味を持った世界中の開発者がgithub上でNode.jsの開発に多数参加するようになり、現在も急速な勢いで開発が進められています。

Node.jsは、奇数のバージョンが開発版、偶数のバージョンが安定版と分かれており、現在まで4つの安定版がリリースされています(2012年7月時点ではnode-v0.8.xが安定版の最新です)。2010年11月よりNode.jsの開発は、米国のクラウド事業者Joyentに移管され、その他の世界中のクラウド事業者やスタートアップ企業が多数開発に関わっています。また2011年からはMicrosoftがNode.jsの開発に参加し、現在、Windows Azureサービス上でもNode.jsが提供されています。

Node.jsのしくみ

次に、Node.jsのアーキテクチャ概要を図に示します。

Node.js アーキテクチャ概要(v0.6~)

Node.jsは、現在Linux、BSD系OS(Mac OS/FreeBSD/OpenBSD)、Solaris(SmartOS)、Windowsの4種類のOSをサポートしています。それぞれのOSに固有の非同期I/Oのシステムコール(epoll/kqueue/eventport/IOCP)を利用していますが、Unix系OSでは非同期I/Oのシステムコール(epoll/kqueue/event port)を利用するために「libev」ライブラリを使用しています。Windows環境では固有の非同期システムコール(IOCP)を利用するため、Node.jsはnode-v0.6より両者を統合した独自のイベントライブラリ「libuv」を開発し、Unix/Windows両方で同一のAPIを利用できるようにしています。

Node.jsのコアモジュールは、プロセスやモジュール管理、tcp/udp通信、ファイル操作といったサーバサイドアプリケーションで求められる基本的な機能を提供するモジュール群で構成されています。いくつかのコアモジュールはhttpのヘッダ解析を行うhttp-parser、SSLの暗号化を行うopenssl、データの圧縮を行うzlibなどの外部モジュールを利用しています。コアモジュール群は、JavaScriptとC++で書かれ、JavaScriptエンジンのV8と非同期I/Oライブラリのlibuvと供にNode.jsの基本的な実行環境を提供しています。また、Node.jsでは、JavaScriptやC++で書かれた外部アドオンを読み込むモジュール機能が提供されています。この機能を使うことで、ユーザはコアモジュールの上に独自のユーザモジュールを作成でき、先述したnpmを利用してユーザモジュールを公開したり、利用したりすることが可能になります。

Node.jsのコアは、サーバサイドアプリケーションで必要となる機能をできるだけシンプルにユーザに提供し、各自の用途、利便性に合わせた実行環境が作れるよう配慮されています。そして現在も、更なる安定性と性能の向上を優先して、Node.jsの開発が進められています。

Node.jsは万能ではない

注目されているNode.jsにも、いくつかデメリットや課題が存在しています。その一部をここで紹介します。

向き・不向きが分かれる利用用途

非同期I/Oイベントを監視するイベントループは、Node.jsの心臓です。CPUリソースを大量に必要とするJavaScriptの処理を行うとイベントループが回らない状態になり、イベントハンドリングが行えない状態に陥ります。このため、CPU処理が大量に必要とされるアプリでは一般的にNode.jsの利用は向きません。また大量の静的コンテンツを提供するサーバなどでは、そもそも多数のイベント処理がそれほど必要なく、Node.jsを使うメリットがほとんどありません。逆に処理が非常に短時間でイベント処理が重要なアプリ(よく言われるチャットアプリ)などでは、Node.jsはそのメリットを最大限に生かせる領域です。このようにサービスによってNode.js利用の向き、不向きが大きく分かれますので、事前によく適性を見極めておく必要があります。

マルチコアサーバで性能を十分に発揮できない

前述したとおり、Node.jsは基本的にシングルプロセス・シングルスレッドで動作します。しかし、そのままの利用では、最近の高集積化したマルチコアサーバ上ではハードウェアの性能を十分使い切ることはできません。node-v0.6からはクラスターモジュールが導入され、Node.jsがマルチプロセスで動作するようになりましたが、マルチプロセスを意識してプログラミングの設計をする必要があります。一方、Node.jsはシングルCPUの環境化でもその性能を十分使い切れるため、比較的性能の小さいサーバ上で大きなパフォーマンスを発揮できます。いくつかのデモで数百メガバイトのメモリの利用時に数千同時接続でも処理が滞らなかった実績や、AmazonEC2を使って25万の同時接続を行ったというベンチマーク結果も発表blankされています。

玉石混淆のユーザモジュール

Node.jsのパッケージモジュールnpmは、Node.jsの開発を行う上で欠かせないツールです。npmを使うと第三者が作成したさまざまな機能を簡単に利用することが可能になります。しかしモジュールの登録は誰でも行うことができるため、同じような機能を行うモジュールが異なった開発者から提供されていたりすることがよくあります。登録されているモジュールは、頻繁にアップデートを行いバグフィックスや機能追加しているものから最近全くメンテされていないものまで様々です。利用するユーザは、自分の目的に一番適して実績を持つモジュールを能動的に探すことが必要となります。対応策としてスマートフォンアプリのようにユーザの評判やフィードバックなどの機能が求められていますが、現在のところ実現できていません。

今後Node.jsはどう使われていくのか?

Node.jsの実サービスの利用は世界的に徐々に広まってきています。Node.jsのホームページblankではトップページに実利用の企業名が表示されています。日本でもソーシャルアプリのプラットフォームとしていくつかの企業が試験的に、もしくは実サービスで利用していることも各種勉強会で発表されています。最近では、Node.jsサーバ上のJavaScriptコードとブラウザ上のJavaScriptコードを共通化するIsomorphic JavaScriptという新しいコンセプトも提唱されました。これを実現して今までになかったようなフレームワークサービスmeteorblankが登場しています。他にもeBayは、バックエンドの自社Rest APIをNode.jsで集約して、SQLライクなインタフェースで統一的にリクエストを管理するql.ioというアプリケーションを開発し、オープンソースとして公開しています。このように最近リリースされているJavaScriptのツールやフレームワークには、内部にNode.jsが使われているケースが多くなっています。今後、ブラウザのJavaScript環境が進化すると共にサーバ・クライアントの両方でNode.jsが関わってくる機会が増え、Node.jsの特性が生かしたこれまでにない斬新なサービスが出てくると期待されています。

大津 繁樹

執筆者プロフィール

大津 繁樹(おおつ しげき)

IIJ プロダクト本部 アプリケーション開発部 戦略的開発室
1999年4月、IIJ入社。SIエンジニア・コンサルタントやサービスエンジニアを経て、現在HTML5、Kinectハック、Node.jsなどのアプリケーションの新技術検証・評価を中心に行っている。


ページの終わりです

ページの先頭へ戻る