Node はサーバー側の JavaScript インタープリターであり、サーバーがどのように機能するかという概念を変えることになります。その目標は、プログラマーが拡張性の高いアプリケーションを構築し、1 台 (および 1 台のみ) の物理マシンへの数万の同時接続を処理できるコードを作成できるようにすることです。
はじめに
Node について聞いたことがある、または Node の素晴らしさを宣伝する記事を読んだことがある人は、「Node とは一体何なのか?」と疑問に思うかもしれません。Node のホームページを見ても、まだ何のことか理解できないかもしれません。ノードは? Node は確かにすべてのプログラマー向けではありませんが、一部のプログラマーにとっては苦労しているものかもしれません。
Node.js とは何かを説明するために、この記事では、Node.js が解決する問題、仕組み、単純なアプリケーションの実行方法、最後に Node.js が適切なソリューションである場合などの背景情報を簡単に説明します。この記事では、複雑な Node アプリケーションの作成方法や、包括的な Node チュートリアルについては説明しません。この記事を読むと、ビジネスに使用できるように Node の学習を続ける必要があるかどうかを判断するのに役立ちます。
Node はどのような問題を解決するように設計されていますか?
Node が掲げる目標は、「スケーラブルなネットワーク プログラムを構築する簡単な方法を提供することを目指す」ことです。現在のサーバー プログラムの何が問題なのでしょうか?数学の問題をやってみましょう。 Java™ や PHP などの言語では、接続ごとに新しいスレッドが生成され、新しいスレッドごとに 2 MB の付随メモリが必要になる場合があります。 8 GB の RAM を搭載したシステムでは、理論上の最大同時接続数は 4,000 ユーザーです。顧客ベースが拡大するにつれて、Web アプリケーションでより多くのユーザーをサポートしたい場合は、サーバーを追加する必要があります。当然、サーバーコスト、トラフィックコスト、人件費などのコストが増加します。これらのコストの上昇に加えて、ユーザーがリクエストごとに異なるサーバーを使用する可能性があるため、共有リソースはすべてのサーバーで共有する必要があるという潜在的な技術的問題もあります。上記の理由から、Web アプリケーション アーキテクチャ全体 (トラフィック、プロセッサ速度、メモリ速度を含む) のボトルネックは、サーバーが処理できる同時接続の最大数です。
この問題に対する Node の解決策は、サーバーへの接続方法を変更することです。接続ごとに新しい OS スレッドを生成する (そしてそれに付随するメモリを割り当てる) 代わりに、各接続はノード エンジンのプロセスで実行されるイベントを発行します。ノードは、ロックをまったく許可せず、I/O 呼び出しを直接ブロックしないため、デッドロックは決してないと主張します。 Node はまた、ノードが実行されるサーバーは数万の同時接続をサポートできるとも主張しています。
何万もの同時接続を処理できるプログラムができたので、Node を使って実際に何を構築できるでしょうか?これほど多くの接続を処理する必要がある Web アプリケーションがあるとしたら、恐ろしいことになるでしょう。それは、「この問題があるなら、それはまったく問題ではない」という種類の問題です。上記の質問に答える前に、Node がどのように機能し、どのように動作するように設計されているかを見てみましょう。
ノードは間違いなく何ですか?
はい、Node はサーバー プログラムです。ただし、ベースとなる Node 製品は、Apache や Tomcat とはまったく異なります。基本的に、これらのサーバーはサーバー製品を「すぐにインストールできる」状態になっており、アプリケーションをすぐに展開できます。これらの製品を使用すると、1 分以内にサーバーを立ち上げて実行できます。 Nodeは確かにこの製品ではありません。 PHP モジュールと SSL モジュールを追加して安全な接続を実装することで、開発者が動的な Web ページを作成できる Apache と同様に、Node にもモジュールを Node コアに追加できるモジュール概念があります。 Node には文字通り何百ものモジュールから選択でき、コミュニティはモジュールの作成、公開、更新に非常に積極的で、1 日に数十のモジュールを処理することもあります。 Node のモジュール部分全体については、この記事の後半で説明します。
ノードはどのように機能しますか?
ノード自体は V8 JavaScript を実行します。ちょっと待って、サーバー上の JavaScript は?はい、そのとおりです。サーバーサイド JavaScript は、クライアントで JavaScript のみを使用するプログラマーにとっては新しい概念かもしれませんが、概念自体は突飛なものではありません。では、なぜクライアントで使用されているものと同じプログラミング言語をサーバーでも使用できないのでしょうか?
V8とは何ですか? V8 JavaScript エンジンは、Google が Chrome ブラウザに使用する基盤となる JavaScript エンジンです。 JavaScript がクライアント マシン上で実際に何を行うのかを考慮している人はほとんどいません。実際、JavaScript エンジンはコードの解釈と実行を担当します。 Google は V8 を使用して、C で書かれた超高速インタープリターを作成しました。このインタープリターには、エンジンをダウンロードして任意のアプリケーションに組み込むことができる別のユニークな機能があります。 V8 JavaScript エンジンは、1 つのブラウザーでの実行に限定されません。したがって、Node は実際に Google によって書かれた V8 JavaScript エンジンを取得し、サーバー上で動作するように再構築します。完璧ですよ!優れたソリューションがすでに利用可能なのに、なぜ新しい言語を作成するのでしょうか?
イベント駆動型プログラミング
多くのプログラマは、オブジェクト指向プログラミングが完璧なプログラミング設計であると信じるように教育されてきたため、他のプログラミング手法を軽視しています。 Node は、いわゆるイベント駆動型プログラミング モデルを使用します。
リスト 1. クライアントで jQuery を使用したイベント駆動型プログラミング
// ボタンが押されるとイベントが発生し、それに対処します
// ここの匿名関数内で直接、すべての
// 必要な変数が存在し、直接参照できる
$("#myButton").click(function(){
If ($("#myTextField").val() != $(this).val())
alert("フィールドはボタンのテキストと一致する必要があります");
});
実際には、サーバー側とクライアント側に違いはありません。はい、ボタンをクリックしたりテキストフィールドに入力したりすることはありませんが、より高いレベルではイベントが発生しています。接続が確立されました。これはイベントです。接続を通じてデータを受信することもイベントです。接続を介したデータの流れが停止しますが、これはまだイベントです。
このタイプのセットアップが Node にとって理想的であるのはなぜですか? JavaScript は、匿名関数とクロージャを使用できるため、優れたイベント駆動型プログラミング言語です。さらに重要なことに、その構文は、コードを作成したことがある人なら誰でも馴染みやすいものです。イベントの発生時に呼び出されるコールバック関数は、イベントがキャプチャされた時点で作成できます。これにより、複雑なオブジェクト指向フレームワークやインターフェイスがなく、オーバーエンジニアリングの可能性もなく、コードの作成と保守が容易になります。イベントをリッスンし、コールバック関数を記述し、あとはすべてシステムに任せるだけです。
サンプルノードアプリケーション
最後に、コードを見てみましょう。これまで説明してきたことをすべてまとめて、最初の Node アプリケーションを作成しましょう。 Node が高トラフィックのアプリケーションの処理に最適であることはすでにわかっているので、最大速度を実現するように構築された非常にシンプルな Web アプリケーションを作成します。サンプル アプリケーションに対する「上司」からの具体的な要件は次のとおりです。 乱数ジェネレーター RESTful API を作成します。このアプリケーションは、「number」という名前のパラメータという 1 つの入力を受け入れる必要があります。次に、アプリケーションは 0 からこのパラメータまでの乱数を返し、その結果の数値を呼び出し元に返します。 「上司」はアプリケーションを広く普及させたいと考えているため、50,000 人の同時ユーザーを処理できる必要があります。次のコードを見てみましょう:
リスト 2. ノード乱数生成器
// Node ファイルの中で最も重要な行。 この機能
// サーバーを作成する実際のプロセスを実行します。 技術的には、
// ノードは、
が実行されるたびに、基礎となるオペレーティング システムに通知します。
// 接続が確立されました。この特定のコールバック関数は
である必要があります
// 実行される。 REST APIでWebサービスを作成しているので
// HTTP サーバーが必要です。これには http 変数が必要です
// 上記の行で作成しました。
// 最後に、コールバック メソッドが「リクエスト」を受信していることがわかります
// 'response' オブジェクトが自動的に作成されます。 これはおなじみのはずです
// PHP または Java プログラマーへ。
http.createServer(function(リクエスト, レスポンス) {
// 応答はすべてのヘッダーとリターン コードを処理する必要があります
// この種の処理はサーバー プログラムで自動的に処理されます
// Apache や Tomcat と同様ですが、Node ではすべてを自分で行う必要があります
response.writeHead(200, {"Content-Type": "text/plain"});
// 以下は、ユニークに見えるコードです。 これが Node の取得方法です
// クライアントリクエストから渡されるパラメータ。 URL モジュール
// これらすべての関数を処理します。 解析関数
// URL を分解し、クエリの Key-Value を
に配置します。
// クエリオブジェクト。 「数字」キーの値を見つけることができます
// 直接参照する - JavaScript の利点。
var params = url.parse(request.url, true).query;
var input = params.number;
// これらは、
を作成する汎用 JavaScript メソッドです。
// 呼び出し元に返される乱数
var numInput = 新しい数値(入力);
var numOutput = new Number(Math.random() * numInput).toFixed(0);
// 乱数をレスポンスに書き込みます
応答.write(numOutput);
// ノードでは、この接続を明示的に終了する必要があります。 なぜなら
// ノードを使用すると、接続を開いたままにしてデータをやり取りできます。
// ただし、その高度なトピックについては、この記事では説明しません。
応答.end();
// サーバーを作成するときは、HTTP サーバーを
に明示的に接続する必要があります
// ポート。 標準の HTTP ポートは 80 なので、それに接続します。
}).listen(80);
// サーバーが起動したら、コンソールに文字列を出力し、すべてを知らせます
// 正しく起動します
console.log("乱数ジェネレーターが実行中...");
启アニメーション应用程序
上のコードは、「random.js」という名前のファイルに入れられます。このアプリケーション プログラムを起動して実行するには (HTTP サーバーとポート 80 上の接続を構築するため)、必要なのは、コマンドプロンプトには、次のコマンド:%noderandom.js が入力されます。以下は、サーバーが起動され、実行されているときに表示されるコマンド:
アプリにアクセスします
アプリケーションは稼働中です。ノードはすべての接続をリッスンしています。テストしてみましょう。シンプルな RESTful API を作成したので、Web ブラウザーを使用してアプリケーションにアクセスできます。次のアドレスを入力します (上記の手順を完了していることを確認してください): http://localhost/?number=27。
ブラウザ ウィンドウが 0 ~ 27 の乱数に変わります。ブラウザの「リロード」ボタンをクリックすると、別の乱数が取得されます。これで、最初の Node アプリケーションが完成しました。
Node は何に適していますか?
この時点で、「Node とは何ですか?」という質問には答えられるかもしれませんが、「Node は何に使用されますか?」という別の質問もあるかもしれません。ノード上でメリットが得られる可能性があります。
何に良いのですか?
前に見たように、Node は高トラフィックが予想される状況に最適ですが、クライアントに応答する前にサーバー側のロジックや処理が必ずしも多く必要になるわけではありません。優れたノードの典型的な例は次のとおりです:
RESTful API
RESTful API を提供する Web サービスは、いくつかのパラメーターを受け取り、それらを解析し、応答を組み立てて、ユーザーに応答 (通常はテキストが少ない) を返します。これは、数万の接続を処理できるようにノードを構築できるため、Node にとって理想的な状況です。それでも多くのロジックは必要ありません。基本的には、データベースからいくつかの値を検索し、それらを応答に組み立てるだけです。応答は少量のテキストであり、受信リクエストも少量のテキストであるため、トラフィックは高くならず、最も多忙な企業の API ニーズも 1 台のマシンで処理できます。
Twitter キュー
ツイートを受信してデータベースに書き込む必要がある Twitter のような企業を想像してみてください。実際には、1 秒あたりほぼ数千件のツイートが到着するため、データベースがピーク時に必要な書き込み数をタイムリーに処理することは不可能です。ノードは、この問題の解決策の重要な部分になります。ご覧のとおり、Node は数万の受信ツイートを処理できます。それらは迅速かつ簡単にメモリ内のキューイング メカニズム (memcached など) に書き込まれ、そこから別のプロセスがそれらをデータベースに書き込むことができます。ここでのノードの役割は、ツイートを迅速に収集し、この情報を書き込みを担当する別のプロセスに渡すことです。別の設計 (通常の PHP サーバーがデータベース自体への書き込みを処理しようとする場合) を想像してみてください。データベース呼び出しがチャネルをブロックしているため、ツイートごとにデータベースへの書き込みに短い遅延が発生します。このように設計されたマシンは、データベースの遅延により、1 秒あたり 2000 件の受信ツイートしか処理できない可能性があります。 1 秒あたり 100 万件のツイートを処理するには、500 台のサーバーが必要になります。代わりに、Node はチャネルをブロックせずに各接続を処理し、できるだけ多くのツイートをキャプチャできるようにします。 50,000 件のツイートを処理できるノード マシンに必要なサーバーはわずか 20 台です。
ビデオゲームの統計
オンラインで Call of Duty ゲームをプレイしたことがある方は、ゲームの統計を見るとすぐに何かに気づくでしょう。そのレベルの統計を生成するには、膨大な量の情報を追跡する必要があります。このようにして、何百万ものプレイヤーが同時にオンラインでプレイしており、彼らがゲーム内の異なる立場にいる場合、膨大な量の情報が非常に迅速に生成される可能性があります。 Node は、ゲームによって生成されたデータを取り込み、データの最小限のマージを実行し、データベースに書き込めるようにデータをキューに入れるため、このシナリオに最適なソリューションです。ゲーム内でプレイヤーが発射した弾丸の数を追跡するためにサーバー全体を使用するのは愚かに思えます。Apache のようなサーバーを使用する場合は、いくつかの有益な制限があるかもしれませんが、逆に、専用サーバーを使用してゲーム データのすべての統計を追跡する場合は、 Node を実行しているサーバーで行うのと同じように、これは賢明な選択のように思えます。
ノードモジュール
この記事の本来のトピックではありませんが、読者の人気により、この記事はノード モジュールとノード パッケージ マネージャーの紹介を含むように拡張されました。 Apache の使用に慣れている開発者と同じように、モジュールをインストールすることで Node の機能を拡張することもできます。ただし、Node で使用できるモジュールは製品を大幅に強化するものであり、これらのモジュールは非常に便利なので、Node を使用する開発者は通常、それらのモジュールをいくつかインストールします。したがって、モジュールはますます重要になり、製品全体の重要な部分にさえなっています。
「参考資料」セクションでは、利用可能なすべてのモジュールをリストしたモジュール ページへのリンクを提供しました。モジュールが提供できる可能性を示すために、利用可能な数十のモジュールの中から次のモジュールを含めました。1 つは動的に作成されたページ (PHP など) を作成するためのもの、1 つは MySQL の使用を簡素化するためのもの、もう 1 つは WebSocket の使用を支援するもの、およびモジュールです。テキストとパラメータの解析を支援します。この概要記事は、Node を理解し、(もう一度) さらに深く学習する必要があるかどうかを判断するのに役立つことを目的としているため、これらのモジュールについては詳しく説明しません。利用可能なモジュール。
また、Node の機能には Node パッケージ モジュールがあります。これは、Node モジュールをインストールおよび管理するための組み込み機能です。依存関係は自動的に処理されるため、インストールしたいモジュールはすべて正しくインストールされ、必要な依存関係が含まれることを確認できます。コミュニティに参加して独自のモジュールを作成することを選択した場合は、Node コミュニティへの独自のモジュールの公開もサポートされます。 NPM は、Node のインストールを中断することを心配することなく、Node の機能を簡単に拡張できる方法と考えることができます。同様に、Node に取り組むことを選択した場合、NPM は Node ソリューションの重要な部分になります。
結論
この記事を読んだ後は、この記事の冒頭で抱いた「Node.js とは何ですか?」という疑問が解決され、この質問にいくつかの明確で簡潔な文で答えることができるはずです。もしそうなら、あなたはすでに多くのプログラマーより先を行っていることになります。私は多くの人たちと Node について話しましたが、彼らはいつも Node が実際に何に使われるのかについて混乱していました。当然のことながら、彼らは Apache の考え方を持っており、サーバーはアプリケーションであり、そこに HTML ファイルを置くとすべてが機能します。ほとんどのプログラマーは Apache とその使用法に精通しているため、Node を説明する最も簡単な方法は、Node を Apache と比較することです。 Node は、(いくつかのモジュールを使用して) Apache で実行できるすべてのことを実行できるプログラムであり、構築可能な拡張可能な JavaScript プラットフォームとしてさらに多くの機能を実行できます。
この記事からわかるように、Node は拡張性の高いサーバーを提供するという目標を達成しています。 Google の非常に高速な JavaScript エンジン、V8 エンジンを使用します。イベント駆動型の設計を使用して、コードを最小限に抑え、読みやすくしています。これらの要素はすべて、拡張性の高いソリューションを簡単に作成できるようにするという Node の理想的な目標に貢献します。
Node とは何かを理解するのと同じくらい重要なのは、Node が何ではないのかを理解することです。 Node は Apache の単なる代替品ではなく、PHP Web アプリケーションを拡張しやすくするように設計されています。これ以上真実からかけ離れたものはありません。 Node はまだ初期段階にありますが、非常に急速に成長しており、コミュニティの参加者が非常に多く、コミュニティ メンバーが非常に多くの優れたモジュールを作成しているため、1 年以内にこの進化する製品があなたのビジネスに導入される可能性があります。