Node.jsの基本とその動作原理
1. NodeJSとは?
NodeJSは、Javascript V8 Engineをベースにしたソースコードで、動画サイトやフォーラム、特に限定的な範囲のソーシャルネットワーキングサイトなどのウェブアプリケーションを構築するために使用されます。NodeJSは、世界中の何千人もの開発者によって広く使用されているオープンソースのソフトウェアです。NodeJSは、WindowsからLinux、OS Xなど、さまざまなオペレーティングシステムで動作するため、これも利点の一つです。NodeJSは、プログラミングを簡素化し、最短の時間で処理を行うために、さまざまなJavascriptモジュールとして豊富なライブラリを提供します。
2. NodeJSの特徴
- 非同期: NodeJSのすべてのAPIは非同期(ブロックしない)であり、主にNodeJSサーバーのベースで動作し、サーバーからデータが返されるのを待ちます。API呼び出し後、次のAPIに進むことで、Node.jsのイベント通知機構により、サーバーが前のAPI呼び出しからの応答を受け取ることができます(リアルタイム)。
- 非常に高速: NodeJSはV8 Javascript Engineを基盤にしており、プログラムの実行速度が非常に速いです。
- シングルスレッドだが高いスケーラビリティ: Node.jsは単一のスレッドモデルを使用し、イベントループによって動作します。イベントの仕組みにより、従来のサーバーと比べて要求を処理する際の制限がなく、スケーラビリティを向上させます。Node.jsはシングルスレッドのプログラムで、従来のサーバー(例:Apache HTTPサーバー)よりも大規模なリクエストに対応できます。
- バッファリングなし: NodeJSはデータをバッファリングせず、これらのアプリケーションは主にデータの出力です。
- ライセンスあり: NodeJSはMITライセンスによってライセンスされています。
3. Node.jsの動作原理
Node.jsの主なアイデアは、非同期的な入出力処理を用い、リアルタイムタスクを迅速に実行することです。Node.jsは迅速なスケーラビリティを提供し、高いスループットで多数の同時接続を処理できます。従来のウェブアプリケーションでは、各リクエストが新しい処理スレッドを生成し、システムのRAMを占有しますが、これによりシステムリソースが無駄に使用されることになります。そのため、Node.jsはシングルスレッドで、非同期I/Oを組み合わせてリクエストを処理し、数万の同時接続をサポートできるようにしています。
4. NPM: Nodeパッケージマネージャ
Node.jsを語る際に欠かせないのが、NPMパッケージ管理ツールの構築です。NPMモジュールのアイデアは、Ruby-Gemsに似ており、再利用可能な関数のセット、オンラインリポジトリを通じて簡単にインストールできる設定、異なるバージョンを管理できるパッケージの集合です。
NPMパッケージのリストは、NPMのウェブサイトで検索するか、NPM CLIツールを使ってNode.jsと共に自動的にインストールできます。
現在、人気のあるNPMモジュールには以下があります:
- expressjs.com/ – Express.js、Node.jsのSinatraに触発されたウェブフレームワークで、現在のNode.jsアプリケーションで多く使用されています。
- connect – Connectは、Node.js用のHTTPサーバーフレームワークの拡張で、高性能な「プラグイン」を提供し、Expressの基盤となるプラットフォームとして使用されます。
- Jade – HAMLに触発されたテンプレートエンジンで、Express.jsのデフォルトの一部です。
- redis – Redisクライアントライブラリ。
- coffee-script – 開発者がNode.jsプログラムをCoffeeScriptで記述できるコンパイラ。
- underscore (lodash, lazy) – JavaScriptで最も広く使われているユーティリティライブラリ、Node.jsで使用されるパッケージで、パフォーマンス向上を目的としています。
- forever – Node.jsスクリプトが常に実行されることを保証する最も人気のあるユーティリティです。予期しない障害に直面しても、Node.jsプロセスを運用環境で維持します。
5. Node.jsの例
チャットは、Node.jsの最も典型的なリアルタイムのマルチユーザーアプリケーションであり、複数の専用およびオープンプロトコルを使用して、標準でポート80を介してWebSocketsを使ってすべての処理を実行します。
実際のチャットアプリケーションは、Node.jsの典型的な例です。これは、高トラフィックでデータ集約型(ただし計算処理は少ない)の情報交換アプリケーションで、分散型デバイス上で動作します。また、学習のために最適なケースでもあります。シンプルでありながら、Node.jsの典型的なアプリケーションで使用されるほぼすべてのモデルを含んでいます。
最も簡単な例として、私たちのウェブサイトに単一のチャットルームがあり、そこではユーザーが1つまたは複数のメッセージを交換できます(実際にはすべて)。例えば、ウェブサイト全体で3人のユーザーが掲示板に接続しています。
サーバー側では、次の2つを実行する簡単なExpress.jsアプリケーションがあります:
- GET ‘/’ は、掲示板と新しいメッセージの開始用の “Send” ボタンを含むウェブページを提供します。
- WebSocketサーバーが、新しく送信されたメッセージをWebSocketクライアントから受信します。
クライアント側では、”Send” ボタンのクリックイベントを処理するHTMLページがあり、入力メッセージを選択してWebSocketを介して送信し、別のクライアントWebSocketから新しいメッセージを受信します(すなわち、他のユーザーによって送信されたメッセージで、サーバーがすべてのクライアントに表示したいものです)。
クライアントがメッセージを送信する際にどのように処理されるかを分析してみましょう:
- ブラウザは、JavaScriptのハンドラを通じて “Send” ボタンのクリックイベントを捕捉し、入力フィールド(すなわちテキストメッセージ)から値を取得し、WebSocketメッセージを使用してWebSocketサーバーに送信します(ページ作成時にWebSocketクライアントが初期化されます)。
- WebSocket接続のサーバー側はメッセージを受け取り、それをすべての接続されたクライアントにブロードキャストします。
- すべてのクライアントは、新しいメッセージをプッシュ通知として受け取り、WebSocketクライアントサイドコンポーネントを通じてウェブページを更新します。これにより、彼らは新しい投稿をブロードキャストに追加します。
これは最も単純な例です。より強力なソリューションには、Redisベースのシンプルなキャッシュを使用できます。また、より高度なソリューションでは、メッセージのキューイングを使用して、メッセージをクライアントにルーティングし、より強力な配信メカニズムを構築して、接続の一時的な損失やオフラインの顧客向けにメッセージを保存することができます。しかし、どんな改善を加えても、Node.jsは基本的な原則に従い続けます:イベントに反応し、同時接続を処理し、ユーザーエクスペリエンスの流動性を保つことです。
参考資料