Simon Willison「Node.jsは超エキサイティング」
Simon Willisonによる2009.11.23のブログエントリ
Node.js is genuinely exciting
Node.jsの詳しいレビュー。速い理由はV8だけじゃない、等々勉強になる。
以下斜め読んだ内容
Evented I/Oとは?
- イベントドリブンなサーバーは、従来のスレッド/ブロックメカニズムへのオルタナティブ
- スレッド/ブロックメカニズムはサーバーサイドプログラミングで主流
- おさらい:よくあるWebフレームワークの動き
- 利用できるサーバーのスレッド・プロセスからの命令で、少数のリクエストを同時にさばく
- 長時間かかる処理は利用できるスレッド1つと結びつく
- 利用できるスレッドがなくなればサーバーは応答しなくなる。
- 大規模なトラフィックをさばくときは、できるだけ早く処理して、割り当てたスレッドを開放して、順番待ちしてる処理へ渡さないといけない
- よくあるWebフレームワークで対応が難しいところ
- イベントドリブンプログラミングでは、ネットワークサーバーがI/O周りの処理がが完了するまで待機していることを利用する
- メモリ上のデータへの処理は超速いが、ファイルシステムへのアクセスやネットワークをまたぐような処理は、レスポンスに時間がかかる。
- Twisted/EventMachine/Node.jsがやってること
- コールバックとリンクしたI/O周りの処理を特定していく
- 単独のイベントループがタスクのリストの中で素早く切り替え、I/O処理を発火させ、次のリクエストをさばけるように移行する
- I/Oが返ると、特定のリクエストの実行が再度ピックアップされる
イベントドリブンなフレームワークが既にある。Node.jsのどこがエキサイティングか
- javascript
- コールバック扱うのが得意な言語
- イベントドリブンなプログラミングが当たり前になってる言語
- しがらみゼロ
- 軽量
- APIのドキュメント30分くらい読んだら大体のアイディアが掴める規模。
- 速い
- すぐ始めれる
- Nodeは必要モジュールが全部まとまってる。Snow Leopard上でカンタンにコンパイルできる
Node.jsを動かす
- 割愛(git cloneからmake、等々)
Node.jsでHello World!
var sys = require('sys'), http = require('http'); http.createServer(function(req, res) { res.sendHeader(200, {'Content-Type': 'text/html'}); res.sendBody('<h1>Hello World</h1>'); res.finish(); }).listen(8080); sys.puts('Server running at http://127.0.0.1:8080/');
Macbookでベンチマーク取った(要 Apache Benchのインストール)
ab -n 1000 -c 100 'http://127.0.0.1:8080'
- 同時接続100で1000回リクエスト出すテストして、1秒に3374リクエストさばいた
- 改変してsetTimeout使ってリクエストを2秒後ごとに設定しても、1秒に50リクエストさばく。結構優秀
- .finish()重要
- リクエストされた処理が完了したことを明示的にシグナルを出し、ブラウザに戻るべきだと伝えてる
- .finish()によって、cometライクなlong-polling/streamingの実装がとてもカンタンになってる
- Node.jsのコアAPIは低レベル
- httpクライアント/サーバー
- DNSハンドリング
- 非同期ファイルI/O
- Node.jsは高レベルAPIを提供しない
作ってみた:djangode
- Node.jsにURL操作機能を拡張
- Djangoで使ってる正規表現を使ったURLハンドリングをしてる
- まだプロトタイプ。Node.js触ってみたアイディア浮かんだら追加していく
作ってみた:nodecast
- あとでかく
データベースの操作
- nodecast自体ではメッセージはメモリ上に配列使って保存。
- じゃあ、データの永続性はどうなってる?となる
- データの永続性についての手っ取り早い解決は、NoSQL系
- Node.jsのI/Oブロックしないという設計は、通常のデータベースライブラリと相性悪い(不可能じゃないが)
- 通信プロトコルはシンプルがいい
- (固有プロトコルじゃなく)TCP/IP上に実現されるシンプルなプロトコル使えるデータベース
- もっといいのは、プロトコルがHTTP使うデータベース
- NoSQL系のCouchDBとredis使ってみたが、動作はとてもよい
- CouchDB用のクライアントで使ったのはnode-couch
- redis用クライアントで使ったのは、redis-node-client
- 自分が作ったnodecastではredisにメッセージキューが保存されてる。
- データベースへ保存する動作書いたコードの部分は、コールバック使った、I/Oブロックしないデータベースインターフェースのいい見本になってると思う
- MySQLもPostgreSQLもちゃんと使える
- PostgreSQLはRyan謹製のNode.js製クライアントあり
- MySQLは少し面倒
Mixed Environments
- Node.jsに開発を完全移行はまだしないけど
- 従来のサーバーサイドプログラミングとNode.jsベースの開発の共存はできる
- Node.js用にサブドメイン切るとか
- プロキシサーバーの後ろで従来のサーバーとNode.jsサーバーを動かす