Node.jsは癌だ。
そう云っている人がいる。
まあぁ~、それは真実である。
実は単純なプログラムでさえI/Oブロッキングしないように記述するのは大変なのだ。
- ファイル1を読む。
- ファイル2に書き出す。
こんな単純な2行プログラムでも、ファイル1がHDDにあるだけで、I/Oブロッキングしかねない。
UNIX風に書けば、
cat ファイル1 > ファイル2
である。
世の中広いから・・・
一行だからI/Oブロッキングで待ちぼうけを食らう2行目が無いので、
ありえないとか言い出す奴もいるかもしれない。(爆
が、
#
が出てくるまで1分もかかれば立派なI/Oブロッキング状態だろう?
だって、#を待っているボクが居るのだから。
UNIXのシェルの逐次処理(一行づつしっかり手順を踏んで実行する処理の仕方)とはそう云うものであり、
そうUNIXだろうが、Javaだろうが、Windowsだろうが、MS-DOSだろうが、コマンドプロンプト(端末)はどれも同じである。
これを回避するためには、イベント・ドリブンなプログラム構造が必要だ。
例えば、
イベント・マネージャに
イベント1:ファイル1を読み終わった。
実行1:ファイル2に書き出すイベント1を実行する
とイベントを登録する。
な様な感じでI/Oブロッキングする部分をイベント・マネージャに繋いでもらう必要があるので、
たった2行のプログラムを2つに別けなくてはいけない。
ということは、I/Oブロッキングの可能性がある箇所がいっぱいあるプログラムはかなり分割しなければならない。
もし、大量のコードからI/Oブロッキングを探し出し、プログラムを分割するのは厄介な話だ。
だから、
Node.jsは癌だ。
# cat ファイル1 > ファイル2 &
で十分だと云いたいのだろう。
見慣れた例で云えば
Windowsのコマンド・プロンプトで
# cat ファイル1 > ファイル2
# が出るまで、他にやることを片付ける。
かもしれないが、
ドコかで、誰かが、I/Oブロッキングを隠ぺいしていることに違いは無いのだ。
これは、UNIXだろうが、Javaだろうが、Windowsだろうが、MS-DOSだろうが、同じである。
それにCPUパワーを裏で使っているので、
1コマンドで1分かかるなら・・・
# cat ファイル1 > ファイル2 &
・・・
# cat ファイル1 > ファイル2 &
と1000回打てばHDDだったら、とんでもないことになる点を見ないようにしているトコロがズルい。(ココが問題なのにね。
これも、UNIXだろうが、Javaだろうが、Windowsだろうが、MS-DOSだろうが、同じである。
見慣れた例で云えば
Windowsで、大量のファイルをコピー!重い!
暇!
その間にEXCELで重いシートを開く!
とかすると両方がHDDを奪い合い・・・
EXCELが(反応しません)になってる!
な状況と思ってくれればいい。
こんな考えで作られたWEBサーバーだからこそ、24時間監視しないと困ると云っていい。
つまり、Node.jsは、CPUの速さの割に、遅いDDRメモリやHDDが実在すると、
並行処理なんてしない方がマシじゃないの?
という現実味のあるところから出てきたものでもあるのだ。
だから、Node.jsでのI/Oブロッキングが発生するのは当たり前として、
設計レベルで通信と実際の処理を非同期化して対処できてしまうので、別に気にしなくても良い問題でもある。
タスク1:リクエストを受信した ⇒ タスク・リスクの最後に追記する ⇒ 「受信しました。結果をお楽しみに」と返信を返す。
タスク2:タスク・リスクの先頭のリクエストを読み実行するを永遠に繰り返すスレッドを1000個動かしておく。
と、するだけで容易にI/Oブロッキングは隠ぺいされる。
更に処理時間の実績が一定以上(我慢の限界)を越えたものは自動的にフラグを立てて、一度に複数の処理を実行しないように(Javaならsynchronize宣言かな?)制御するともっとよいだろう。
# ********** & 式にバックグラウンド処理へドンドン投げる方式よりは、遥かにマシだろう?
注:当初はバックグラウンド処理へドンドン投げると詰まってしまうならサーバーを増やせばよい。と云うことになっていた。
後は、ブラウザのHTMLの中のJavaScriptに非同期通信の受信イベントで返信を受け取る様に仕込んでおけばよいのだ。
てか、WEBで1000個のスレッドが目詰まりするような処理は、別のサーバーに分担させるのが、王道だろう?
これも、UNIXだろうが、Javaだろうが、Windowsだろうが、MS-DOSだろうが、同じである。
更に付け加えれば、
Apacheの様に多数のスレッドが目詰まりするような事態が起きればクラッシュしかねないサーバーには到底任せられない処理をガンガンとI/Oブロッキングが起きることを理解しつつあえてNode.jsで実装する方がマシだったりする。
と云うのも、Node.jsで作ったサービスが落ちたら、そこだけ、
再起動!
すれば良いだけなので、とても簡単だからだ!
どうせ、オンライン・サーバーは全部監視しているのが常なので、
サーバーを分割したから、落ちてたのを気が付かなかったらどうする?とか、考える方が変なのだ。(大笑
仮に、オンライン・サーバーを一本化し、入念に監視することで、稼働監視を完全なものにすると考えたとしよう。
しかし、それは無意味だ。
炎上すれば、止まってしまうか、止めてしまうかの違いでしかない。
あえて云えば、高価なサーバーはそうそう増やせないというところか。
だからこそ、重い処理は、止められない高価なサーバーから、止まってもいい高価なサーバーへ移し替えるべきなのだ。
入口の処理が心配なら、並の数台のサーバーを用意して、分散処理させれば、かなり安く仕上げられるだろう。
つまり、最前線に歩兵を行かせて、後方から高価な戦車で援護射撃する手法である。
実際の戦場でこんな運用をやったら死人が出過ぎて話にならない様な気もするが、遮蔽物の少ない砂漠等では有効な戦術である。
それにWEBの話なら、死ぬのはレンタル機器、しかも再起動すれば生き返るゾンビーサーバーなので、困らない。
要は使い様なのである。
話がそれてしまったが・・・
コンピュータ言語の良しあしは、使い道が間違っているトコロで論じられることが多い。
そこが主な原因であって、言語自体に特に問題はない。
古臭いCOBOLでさえ、まっとうな使い道があるなら、使えばよいだけの話である。
もっとも、それができるSEがどれだけいるか?
と問われたら・・・
実在しないだろうな・・・
としか答えられない。
だって、一つのシステムにそれぞれに最適な言語を割り当てたら10以上になった・・・とか
目も当てられないですからね。
それにボクがCOBOLが嫌いなのは、実はそれを扱う仕事のやり方が嫌いなのである。
例)プログラムを作り、デバッグを終えた後に、変数の名前を揃えるから、やりなおせ等。
と云うところに重点を置いているのであって、COBOL自体はどうでもいいだ。
使い物ならないなら、使わないだけなのだから。