Node.jsの問題点、デメリットと解決方法まとめ


技術選定のためや、俺が問題解決するぜっ!的な人向け。

順次解決されると思うので、順次更新します。
以下に上げたものも、解決策があるものが多いです。


## はじめてのNode.js (2013年3月26日初版)

* どこか1か所CPUリソースを多く消費するような重い処理が入ると、全体のパフォーマンスが低下する
* マルチコア/マルチCPU環境を十分に生かすことができない 
* コールバックを多用するためにコードが複雑になる

## merittyの記事 (2012年12年23日)

[Node.jsのメリットとデメリット | meritty [メリッティ]](http://www.meritty.com/titles/detail/52 "Node.jsのメリットとデメリット | meritty [メリッティ]")

> * JavaScriptの限界、オブジェクト指向が不完全
> * マルチコアサーバで性能を十分に発揮できない
> * 文法エラーが、サーバーの停止を引き起こす
> * あるリクエストに問題があると、他のリクエストをブロックする


## ZEALOT社員の方 (2012年10月29日)

引用: [Node.jsについて個人的なまとめ | Z BLOG | ZEALOT社員ブログ](http://blogs.zealot.co.jp/archives/30 "Node.jsについて個人的なまとめ | Z BLOG | ZEALOT社員ブログ")

> * まだ商用で使うには不安定な部分がある。
> * 開発者が少ない。 : JavaScript開発者がNode.jsの開発者ではない。
> * メジャーでもない。
> * 非同期処理なのでエラーハンドリングが難しい。
> * 基本的にシングルプロセスなのでどこかでシステムエラーが発生するとサーバダウン。
> * Hot deployができない。

## GREE CTO藤本さん (2012年8月)

引用: [GREEが悩むNode.jsの問題を考えるヒント - ぼちぼち日記](http://d.hatena.ne.jp/jovi0608/20120809/1344474864 "GREEが悩むNode.jsの問題を考えるヒント - ぼちぼち日記")

> 1. ひたすらすごい勢いでバージョンアップしているので安定しない。コストを払ってついていく覚悟を持って取り組んでいる。
> 2. メモリリークがあるので、サーバを起動しっぱなしにするとメモリが食いつぶされる。
> 3. コードをデプロイしても再起動しないと読み込まれない。

解決策は、上記リンク先に書いてあります。

## IIJ 

> node-v0.6からはクラスターモジュールが導入され、Node.jsがマルチプロセスで動作するようになりましたが、マルチプロセスを意識してプログラミングの設計をする必要があります。

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

[注目のサーバサイドJavaScript実行環境「Node.js」 | 最新の技術動向 | IIJ](http://www.iij.ad.jp/company/development/tech/activities/nodejs/ "注目のサーバサイドJavaScript実行環境「Node.js」 | 最新の技術動向 | IIJ")

## デブサミ (2012年2月)

[ソーシャルアプリのインフラはNode.jsが主役になるか～デブサミまとめレポート（ソーシャル＆インフラ編） - ＠IT](http://www.atmarkit.co.jp/fsmart/articles/devsummit2012_01/01.html "ソーシャルアプリのインフラはNode.jsが主役になるか～デブサミまとめレポート（ソーシャル＆インフラ編） - ＠IT")

> 例えばNode.jsはI/Oや大量データ処理には強いものの、シングルスレッドでCPUパワーを使うようなタスクには弱い。そこで、結果はできるだけキャッシュするなどしてCPUリソースを節約する工夫が必要になる。HTMLのテンプレートやレンダリングなどはCPUリソースを消費するので、クライアントに処理を委譲してしまう対策も有効だという。 

> データアクセスに関しては、Node.jsの処理は非常に高速だが、その分リクエスト回数が増えてDBに負荷を掛けることになる。そこで、制約をアプリケーションレベルで保持することによってDBの処理を低減しているという。

> 逆にNode.jsは、数値解析などプロセッサ処理が中心的となるような処理に対しては不適切

> 定期的に発生するV8エンジンのGC（ガベージコレクション


## ブログ記事 (2011年2月20日)

[node.jsは普及しそうに無い: ニュースの社会科学的な裏側](http://www.anlyznews.com/2011/02/nodejs.html "node.jsは普及しそうに無い: ニュースの社会科学的な裏側")


>1. イベントループ・モデルで処理を直列化しているので、あるリクエストの処理に時間がかかる場合、他の全てのリクエストをブロックする可能性がある。
>2. イベントループ・モデルで平行処理を行わないため、複数コアを持つCPU/MPU、複数のCPUを使うSMPでパフォーマンスの上昇が、JavaScriptのコード部分は期待できない。
> 3. JavaScriptのプログラミング言語としての限界が影響する。つまり、オブジェクト指向が不完全であること、動的型付けでJavaやC#に対して速度面に限界があること等が、大規模で複雑なアプリケーションには影響を及ぼす可能性がある。 
> 4.あるページを表示するためのサーバー側のJavaScriptの文法エラーが、サーバーの停止を引き起こす。簡単なプログラム・ミスが、アプリケーションの非クリティカルな部分に発生したとしても、システム全体がダウンする結果となる。
> 5. 非同期化によるパフォーマンス向上がイベントループ・モデルに依存するため、イベントを受けるコールバック関数が多くなり（単純なファイル操作でも3回コールバックが発生する）、ソースコードの見通しが悪くなる。
> 6. 利用可能ライブラリが限定的であり、開発支援ツールが無い。Apacheモジュールも種類や用途が多いし、JavaやPHPにも覚えきれないほどのフレームワーク製品群とライブラリがある。これらに依存しない用途にしか、現状では利用できない。

上記、解決策は上記引用元や以下でも指摘があります。
[Node.jsについてのよくある誤解 - 自分の感受性くらい](http://meso.hatenablog.com/entry/20110220/1298202879 "Node.jsについてのよくある誤解 - 自分の感受性くらい")

## 解決策

### 開発時の再起動問題

以下のモジュールを利用して、ファイル変更を検知して再起動する

* nodemon
 [remy/nodemon](https://github.com/remy/nodemon)

* supervisor
[isaacs/node-supervisor](https://github.com/isaacs/node-supervisor)

* node-dev
[fgnass/node-dev](https://github.com/fgnass/node-dev "fgnass/node-dev")

* hotnode
[saschagehlich/hotnode](https://github.com/saschagehlich/hotnode "saschagehlich/hotnode")

* always
[edwardhotchkiss/always](https://github.com/edwardhotchkiss/always "edwardhotchkiss/always")

* Qilin (麒麟? 作者は日本人の方)
[atsuya/qilin](https://github.com/atsuya/qilin "atsuya/qilin")

### 本番サーバでのホットデプロイ問題

* forever, up, pm2

### コールバック地獄問題

* future, promise, delay 並列処理のデザインパターンを使う
[future - Wikipedia](http://ja.wikipedia.org/wiki/Future "future - Wikipedia")
* 定番の async.js を使う
* yield を使う (Node.js version 0.12以降)

### 重い処理で処理が待たされる

* child_process.fork(filepath)

 [node.jsでCPUを使う重い処理のlibrary (child process使い) を1 fileで作る - c4se記：さっちゃんですよ☆](http://c4se.hatenablog.com/entry/2013/10/25/131245 "node.jsでCPUを使う重い処理のlibrary (child process使い) を1 fileで作る - c4se記：さっちゃんですよ☆")

* fugue, Spark2, cluster

* process.nextTick()  (v.0.10.xまで?ループで一回処理ならこちら)
* ループでn回の処理が必要なCPUヘビーな処理の場合、 setImmediate() 


### マルチスレッド

[Node.js でマルチスレッド対応のネイティブモジュールを作成する - 凹みTips](http://d.hatena.ne.jp/hecomi/20121021/1350819390 "Node.js でマルチスレッド対応のネイティブモジュールを作成する - 凹みTips")

### 文法エラーで止まっちゃう問題

* 事前対策
 * 例外をキャッチする
 * Event: uncaughtException のリスナを登録
 * JSLint, JSHint等をコミットフックやデプロイ時に仕掛ける
 * ユニットテストを行う
* 事後対策
 * 監視して再起動する

### エラーハンドリング問題

調査が甘いので、偉い人教えて下さい。

* 非同期コードの例外をキャッチする独自モジュール（node-gree）


### メモリーリーク問題  

* node-v0.10.22 のファイルハンドラのメモリーリーク修正で解決? (コメントより。 thx shigeki@github)


## 時が解決する問題

* 頻繁なバージョンアップ
* 安定性問題 
* Node.js 技術者が少ない
* ドキュメントが少ない問題

## 偉い人が解決してくれるだろう問題

* JavaScript の言語仕様の問題
 * オブジェクト指向

## 解決されていない問題

* 玉石混淆のユーザモジュール
*  npm 上の評価システムの実装