Takahiro Octopress Blog

-1から始める情弱プログラミング

昔関わったNode.jsを思い出してみる

はじめに

本日は久しぶりにNode.jsについて書きたいと思います。
筆者が本格的にNode.jsを触っていたのは、3〜4年ほど前で、当時は今ほど存在が浸透してはいませんでした。
それが今やサーバサイドの処理作成の選択肢の1つとして普通に検討される時代になりました。
正直なところ、最新のNode.jsを追えているわけではないのですが、
その本質は今も昔も大きくは変わっていないだろうと思いつつ、筆者の経験を元にNode.jsを見ていきたいと思います。

Node.jsとは

Node.jsは2009年にライアン・ダールによって作成された『JavaScriptをサーバサイドで実行可能にしてくれるプログラム』です。
JavaScriptエンジンは Google V8 JavaScript エンジン を使っています。
因みに、 Google V8 JavaScript エンジン とは、

  • ECMAScript5に準拠
  • C++で記述されている
  • スタンドアローンで動作可能
  • Google Chromeでも使われている

というものです。
これを見ただけでも何となくすごいな〜と思ってしまいますね笑。

Node.jsの公式サイトはこちらです。
日本ユーザグループサイトもありますが、今は活動的に更新されていません。

Node.jsの特徴

続いて、Node.jsの特徴を見ていきましょう。
Node.jsの特徴は、何と言っても

  • イベントループモデル
  • Non-blocking I/O
  • シングルスレッド

ではないでしょうか。
筆者がNode.jsを触っていた時は正直全く理解していなかったのですが、
これらこそがNode.jsの本質でしょう。

イベントループモデル

イベントループモデルと一言聞くと、「なんぞや!?」となってしまいそうですが、

  • イベントの発火を常に監視しているループ
  • イベントの発火を受け付けると、イベントキューに格納される
  • 受付順にイベントを処理していく

という方式のことです。

Non-blocking I/O

I/O処理を受け付けた場合、I/O処理が完了するまで待つ(Blockされる)のが通常です。
Node.jsではI/O処理を投げつけた間、他にやるべき処理があれば進んで実行してくれます。
よって Non-blocking I/O と呼ばれています。

シングルスレッド

言葉のとおりですが、複数のリクエストを1つのスレッドで実行するということです。
複数スレッドを生成するわけではないため、メモリ消費を抑えることができると言われています。

Node.jsのメリット/デメリット

Node.jsが全てのアプリケーションに最適なのかと言うとそんなことは当然ありません。
Node.jsのメリット/デメリットを理解した上で、採用を検討する必要があるのです。

Node.jsのメリット

まずはメリットを見ていきましょう。

  1. 大量の軽量な同時リクエストを捌くのが得意
  2. NoSQLとの親和性が高い
  3. JavaScriptで書ける
  4. 充実したライブラリが存在している

筆者の経験に基づくメリットを4つ上げさせて頂きました。

1つ目の 大量の軽量な同時リクエストを捌くのが得意 というメリットですが、
これはNode.jsの特徴で上げたことが関わってきます。
Non-blocking I/Oなので、I/Oブロックしないとは言うものの、Node.jsはシングルスレッドなんです。
なので、1つのイベント処理の中に非常に時間のかかる処理が含まれていると、そこがネックとなってしまい大量のリクエストを待たせてしまいます。
場合によってはクライアント側で設定したタイムアウト時間を上回り期待した結果をユーザが得られなくなるでしょう。

なので1つのイベント(1回のリクエスト)で非常に重い処理を実行させなくてはならない仕様が求められるサービスには向きません。
逆に、細かくイベントを分割できて、複数回のリクエストをクライアントから送っても問題のない仕様のサービスには適切と言えます。

2つ目の NoSQLとの親和性が高い というメリットですが、
筆者は主に MongoDB と一緒に利用してきました。
MongoDBはドキュメント指向データベースであるため、JSON型のデータをそのまま突っ込めるため非常に使いやすいのです。
スキーマレスかつスケールアウトの特徴を存分に活かしたい場合はNoSQLを選択すると思いますが、
そこから遡ってNode.jsを選択しても良いでしょう。

3つ目と4つ目のメリットですが、
フロントエンドエンジニアであれば、基本的にはJavaScriptを扱えるという人もたくさんいるかと思います。
であれば同じ言語のJavaScriptで書けるNode.jsを採用しない手はないでしょう。
また、MongoDBもNode.jsもJavaScriptにも言えることですが、初心者を割りとすんなり受け入れてくれる土台が整っているため、
1人でサービス提案時のモック作成をしなくてはならないときなどに最適です。
(誤解されたくないのが、どの技術も極めるにはかなり大変ということに変わりはないということです。)

Node.jsのデメリット

続いてデメリットを見ていきましょう。

  1. 重いリクエストを捌くのが苦手
  2. コールバック地獄

1つ目のデメリットはメリットで書いた内容です。
2つ目はまさに筆者が3〜4年前に感じていたデメリットです。
Non-blocking I/Oの特徴を持つ代わりにソースコードを書いた際に複数回ネストすることが少なくありません。
(サーバダウンを防ぐためにtry-catchを入れようものなら尚更です。)

ただし、v0.12からyieldが追加されましたし、
今やWebに限らずスマホネイティブの世界でもPromiseの利用が珍しくはないため、最早デメリットとも言えなくなったと思われます。

また、筆者的には
HTML, CSS, JavaScriptや画像などの静的ファイルを返却するようなWebサーバとしての役割はNginxやApacheに任せてしまって良いという感覚です。
むか〜し、計測したイメージが強く残っているからかもしれませんが…

Nodeモジュール

今も忘れない当時使っていた or 助けられたNodeモジュールについて紹介します。

Express

これは最も有名なNodeモジュールではないでしょうか?
( Express の公式サイトはこちらです。)

Express はWebアプリケションフレームワークであり、Webアプリケーションを作成するために必要な機能を提供してくれます。
このモジュールがあるため、サーバサイドを非常に簡単に作成することができるのです。
(玄人になればなるほどアンチExpressが多い気もしますが…)

node-inspector

続いて、こちらも使わない人の方が少ないのでは?と思うくらい重要な node-inspector について紹介します。
(GitHubはこちらです。)

サーバサイドエンジニアはeclipse, IntelliJなどのIDEを利用して開発すると思います。
IDEを利用する理由は様々ですが、その中の1つにデバッグ機能があります。
node-inspector はまるでフロントエンドを開発しているかのごとく、ブラウザ上でデバッグ機能を提供してくれます。

forever

次は、 forever の紹介です。
Node.jsでは想定外のエラーが発生した際にサーバがダウンしてしまいます。
サーバがダウンし、イベントループが停止してしまうと、クライアント側からのリクエストを受け付けることができません。
そのため、サーバを再起動する必要があるのですが、これを自動的に実行してくれるモジュールが forever です。
(GitHubはこちらです。)

log4js-node

先ほども説明した通り、プログラムは所詮、人間が作り上げたものなので、想定外なことは起こりえます。
それに対処するためにエンジニアとしては失敗をただの失敗として放置するのではなく、経験として蓄積し、次に活かすのです。
その手助けとなるのがログです。

log4js-node を利用することで、info, debug, warn, errorなど各種ログを仕込むことが可能となります。

async

実は筆者が最も思い出深いモジュールがこの async です。
Node.jsのデメリットで紹介しましたが、筆者がNode.jsをメインで触っていた3〜4年前はまさにコールバック地獄でした。
また、1回のイベント発火内で非同期処理を繰り返し順番に実行したい要望があり、非常に手を焼きました。
これを救ってくれたのが async なのです。

特に、async.waterfall, async.parallel, async.series, async.eachSeriesは必見の価値ありです。
(GitHubはこちらです。)

その他

その他にも便利なものがたくさん用意されているので必要に応じて利用すると良いでしょう。

  • mocha: Node.jsのためのテストフレームワーク
  • socket.io: WebSocket機能を実装できるモジュール
  • mongoose: Node.jsからMongoDBを利用するためのモジュール
  • mysql: Node.jsからMySQLを利用するためのモジュール
  • sails: Ruby on RailsライクなMVCフレームワーク

Node.jsを勉強するための近道

最後にNode.jsの勉強方法について紹介したいと思います。
筆者的には、まずは JavaScript をきちんと学ぶことが必要だと思います。
クライアントサイドから始めても、サーバサイドから始めても構わないのですが、クライアントサイドからの方が始めやすいのではないでしょうか。

また、サーバサイドでNode.jsというものが何かを学ぶのであれば、
Nodeビギナーズブックを1回は読んでおくことをオススメします。
市販されている本を読むよりも本質的な部分を理解できると思います。
(あと、未だにNode.js関連の本って全然ないので…。)

まとめ

さていかがでしたでしょうか?
Node.jsはまだまだ新しい技術ですし、これからもっと学ぶべきことが増えてくることでしょう。
筆者も極力最新を追えるように精進したいと思います。
と言ったところで本日はここまで。

参考:

Comments