以下斜め読んだ内容

pseudo translation of useful posts, book reviews, remarks,etc. twitter: feeddict

『Node.js in Action』1章「ウェブがnodeを必要とした理由」

Manningから2012年春に出るnode本のearly access programがスタートしてた

Manning: Node.js in Action

  • 著者は二人
  • early access programのページで脱稿前の原稿がどんどんアップされてく予定で、2011.8.25時点で2章までアップ
  • 導入にあたる1章だけ無料公開してたので斜め読んでみた。既出系トピックは適宜カット
以下斜め読んだ内容
  • ちょっと想像してみてほしいこと
    • いろんな情報を一瞬で送ったり受信したり処理してしまうウェブアプリが現実になった世界
    • 離れたところにいる友達が打ってるメール文面を、逐一みれる世界
    • バス停でバスが現在どこにいるかをスマホの画面で逐一わかる
    • 大勢が同時に参加できるアーケードゲームをブラウザだけでプレイできる世界
  • 現時点でウェブはここで想像した世界をあるレベルでは実現できるところまできた
  • 進化したブラウザテクノロジー(html/css/webGL)。これを活用した洗練されたインターフェース
  • twitterに片鱗を伺うことのできるリアルタイムアプリ
  • リアルタイムウェブアプリ開発
    • これまでプログラミングの定石、既存のウェブフレームワークでは難しい部分
    • スケールアウト、開発スピード、開発しやすさ
  • node
  • nodeの特徴であるデザイン上のチョイス3つ
    • jsエンジンV8のスピードをつかう
    • libev/libeiを使った効率の高いtcp/ipネットワーキング機能
    • 非同期プログラミングスタイルのサポート
    • nodeのデザインによってnodeはスケールしやすく、高速で、可用性の高いプラットフォームになった
  • WordSquared
    • nodeのパワーを示すよい例
    • 48時間で開発されたもの
    • MMOゲーム。
      • (ゲームの仕組み・ルール、獲得したユーザ数部分は割愛)
    • リアルタイムのpush型の通知にPusherを使ってるのが特徴
      • Pusherは人気nodeモジュールsocket.ioと同等の機能提供してて、socket.ioの方が現在はポピュラー
    • pusher/sockect.ioもwebsocketを使ってる
  • 非同期プログラミングスタイルと定石プログラミングスタイルの違い
  • nodeとjsのマッチングの絶妙さ
  • nodeが有力な選択肢になる場面は色々
    • webアプリ
    • tcp/ipで動く新しいプロトコル開発
    • client/server型アプリ
    • コマンドラインツール

1.1 nodeがwebをさらに発展させる

  • 2004年のrailsブーム以降で最もエキサイティングなイノベーションがnode
  • railsがエンジニアの考え方を変えて一世風靡していった様子
    • 割愛
  • nodeは既存のものと違うアプローチを出した
    • テクノロジーをシンプルにしながらも生産性をあげることを具体的に提示
  • そのまえにwebにおけるnodeの歴史的な位置づけをおさらい
  • webの世界におけるインタタラクティブさの徹底、という流れ
  • www初期
    • webはdocumentベース。webアプリもdocumentモデルの影響下。フォームとか
  • 2004年のgmail、2005年google maps
    • documentのメタファーでwebアプリを考えることを過去のものに
    • ajaxという技法を広めた
  • ajaxアプリ
    • 「まあまあリアルタイムな」ウェブアプリ
    • webでのインタラクティブさの可能性を広めた
  • 2006twitterがローンチ
    • ほぼリアルタイムに行われるコミュニケーション
    • 桁違いに大きい数のユーザ向けに刻一刻変わるコンテンツ提供をどうやって実現するか、という問題が全面に
  • 2009年。ryanがnodeつくる
    • 膨大な数のユーザへの情報のプッシュをどうやってこなすか。この課題へのnodeが解決方法を出してくれてる、と解釈されたりもした
    • Node or Node.js?どっちが正しい系の話
      • 割愛
  • nodeのイベントドリブンプログラミング
    • 非同期プログラミングと言う人もいる
    • アプリのロジックを逐次的に書かない
    • アプリが各イベントに対してアプリがどう反応すべきか。これを書いていく
  • nodeのは3層にわかれる
    • まず、nodeのコア層。libev,libeio,v8
    • 次に、コアモジュール
    • 最後に、サードパーティモジュール。nodeコミュティで開発
  • v8の出自の話
    • 割愛
  • jsエンジンの世界でv8がもたらしたイノベーション
    • v8ではjsをコンパイルされる
      • インタプリタに渡されない
      • オンザフライでコンパイル
      • JITコンパイルと呼ばれるテクニック
      • JITは別言語で実績あるテクニック。javaとかsmalltalk
    • v8のコアはVM
      • "an emulated abstraction of a computer that can be programmed the same regardless of what hardware it's running on"
    • v8チームを率いるLars Bakはjavaの世界で色々実績あり
  • pythonハッカーSimon Willisonがnodeに注目し紹介
    • 一気にエンジニア世界に広まった
  • nodeコミュニティ
    • エネルギッシュでフレンドリー
    • ビギナー向けにも情報整理されてる
    • モジュール作者の数は800人以上

1.2nodeが他と違うところ

  • 「シンプルさは信頼性の前提条件」(by Edsger W. Dijkstra)
  • シンプルさとミニマリズム。nodeハッカーに気に入られてるところ
  • ゼロから作られた。トータルに非同期
    • python/twisted,ruby/eventmachineとここがちがう
  • nodeのAPIはシンプル。だけどパワフル
    • コアモジュール
      • たとえばhttpモジュール(httpプロトコル関係の機能)、netモジュール(tcp/ip系の機能もろもろ)などネットワーク系の機能を提供するモジュール群
      • nodeのAPIは通常のウェブアプリが実装できる機能以上のものが提供される
      • websocketサーバ、ftpサーバー、dnsサーバー実装できる
      • udpは?
        • nodeのコアモジュールでサポート
        • udpではデータ送信可否の確認をスキップ。通信の信頼性を保証するステップを省略
        • DNSではUDP使われる
  • スレッドベースのウェブアプリ
    • 事例多い
    • スレッドベースの設計の特徴とかボトルネックとか
      • 割愛
  • nodeではスレッドの代わりにイベントループ
    • イベントループではタスクの管理とかタスク切り替えとかはosレベルではなくフレームワークレベルで処理される
    • イベントループはlibev使って実装
  • ミニマリズムあふれるnodeのデザイン
  • 非同期プログラミング重要
    • nodeと他を差別化するポイント
  • 同期的プログラミングと非同期プログラミングの違い
    • 割愛
  • パスタを料理を比喩ににして、非同期/同期プログラミングの違いを説明
    • 割愛
  • 非同期プログラミングではハンドリングする変数の数が多い
    • 無名関数使うの減らせば尚更
    • 結構ストレスなんだが、ストレス軽減する仕組み・モジュールは開発されてる。4章みろ
  • jsを使う利点
    • jsと非同期プログラミングスタイルの相性
    • 既存言語。非同期プログラミングスタイルのネイティブサポートなし
      • ライブラリが非同期プログラミングスタイルを提供
      • 当然非同期ライブラリ使いたければ学習コスト発生
    • nodeには他にないエレガントさ
    • シングルスレッド、サーバーサイドI/Oについて既存ライブラリがゼロの言語が欲しかったryan
    • ryanにとってjsはパーフェクト
    • jsのシンタックスと命名ルール。c/javaの影響
    • jsは簡潔。java/cよりコード量が少ない。
    • js暗黒時代で横行した過小評価の原因
      • ブラウザ間の互換性の乏しさ、デバッグが難しい。
    • jsの現在
      • ブラウザ間での実装は改善。本来もつ表現力が評価
    • 非同期処理のロジックの記述がjsは得意
    • jsでは関数はファーストクラスオブジェクト
      • 関数は引数にも、戻り値にも、変数への代入。関数はできる
    • コールバック
      • 関数利用のnode頻出パターン
      • 非同期関数の完了時のロジックの記述に使われる関数
      • コールバックは無名関数or定義済み関数
//2つコールバックをもつ関数の例
//関数の成功時用コールバック、失敗時用コールバック
//成功/失敗パターンは、node頻出
function horse_race(success, failure) { var victory = Math.round(Math.random(1));
if (victory) success();
} else { failure();
}
{
console.log('Goodness! I won!'); }, console.log('Drat. I lost.'); }
}
  • jsも動的言語。ruby/pythonとおなじ
    • 動的言語ゆえに
      • 高級言語、生産性も高い
      • コンパイル不要
      • モンキーパッチできる
        • ソースコードはそのままで、コードを一時的に修正して実行する
        • モンキーパッチはphp/javaではできない
      • nodeでは活用するとパワフルに
    • jsコードはブラウザ/サーバー両方で使える
    • 双方へコードを移植できる
    • apiをブラウザからもサーバーからも利用できるように設計、とかできる
    • validation処理を両サイドで書くとかできる
      • 無駄じゃない?という声あり
      • 同じ処理を両側でやるわけ、ロジックの一貫性、「できるだけ少ないコードでメンテしなきゃ」というプレッシャー
  • 普通はクライアント/サーバーサイドで使う言語・フレームワーク違う
    • 頭を切り替える手間。
    • node/jsだとこれがない
    • 生産性と楽しみをアップ
  • ウェブアプリケーション"サーバー"を作る
    • 単にサーバーサイド用のコードを書くだけでは無理
    • httpをサポートしたサーバーを書くことが開発の一部になってる場面はある
      • rails/django。もちろんnodeも
      • phpだと無理
      • phpではapacheをコントロールするためのコードを書くくらい
      • アプリにクリーンなURL(=パラメータや拡張子まみれじゃない)実装したい
        • phpで実装したければmod_rewriteのようなurlようなurl書き換えをするツールが必要
      • phpの外部のウェプアプリケーションサーバーかける開発では、こういうハックはたいてい不要になる
  • nodeでウェブアプリケーションサーバーを書く
    • requestオブジェクト、responseオブジェクトを処理
    • requestオブジェクト、リクエスト出したクライアントの情報がぎっしり
    • responseオブジェクトには、メソッド色々。メソッド使ってクライアントへデータ送る
    • フレームワークがnodeコミュニティから色々リリースされてる
      • アプリケーションサーバーでたいてい必要になる機能を提供する
      • request/responseオブジェクトを活用されてる
      • expressが一番ポピュラー。8章でとりあげる
      • mvcパターンに準拠したnodeフレームワークがたいていサポートしてる機能も提供してる
        • urlパターンとアプリケーションロジックと結びつける
        • セッション機能
        • テンプレートエンジン
      • 画像など各種メディアのサポート
  • おさらい。MVC
    • アプリ構築の作法
    • データ、データ処理のロジック、アウトプット
    • 3つを分離して説明
    • webアプリに話しぼると
      • モデル:db api使ってコントロール。データへのインターフェース
      • ビュー:テンプレート
      • コントローラ:ロジック。(モデルからビューへの)データフローのコントロール
  • mvcオススメ記事は、Jeff Atwoodが書いた記事

1.3 nodeが活躍する場面は多い

  • httpプロトコルを使うアプリケーション以外でもnodeは活きる場面多い
    • nodeアプリでは、httpプロトコルのサポートだけでなくwebsocketなど非httpプロトコルのサポート追加もすぐできる
    • nodeでリバースプロキシ作れる
      • squidVarnishのライバルになるレベルで作れる
    • プロトコルのデザイン
    • コマンドラインツール開発
  • サーバーアプリケーションのデザイン
    • ファイル転送とか、メール送信とか、インスタントメッセージ、など
    • 伝統的にはc/c++/javaで開発
    • c
      • 柔軟な言語、低レベル、習得難しい
    • c++
      • cの拡張、追加機能豊富、使い方間違うとはまる。演算子+の意味がcとc++で変わってる
    • java
      • c++に比べると難しいところは少なめ、cより冗長、動的言語より柔軟じゃない
    • js
      • 開発スピードとサーバーソフトウェアの多様性がアップするはず
    • node/jsで書かれた伝統的サーバアプリケーションは色々プロジェクトがある
  • nodeの低レベルでの能力も活躍できる場面ある
    • 事例としてBrowserling
    • BrowserlingがVM上でテスト走らせる
    • StackVMは動画とキーボード/マウス操作データを中継する
    • VMからユーザが使ってるブラウザへとデータ中継
  • nodeでプロトコルを開発
    • (補足)このトピック話がnodeというよりnode周辺の話題
    • node内でのトレンド2つ
      • リアルタイムウェブ
      • 新しいプロトコルの開発
  • websocketの話
    • (割愛)websocketが策定されてる経緯とかsocket.ioの話とか
  • webの発展の流れ
    • 王道
      • オープンさを尊重。自由にリンクされた世界、標準化されたテクノロジー:html/css/js/rssセマンティックウェブ
      • オープンな世界でデータを構造化していこうとする流れ
    • 別の流れ
      • 最近存在感出してきてる
      • facebookなど巨大snsが作りあげてる
    • 情報へのアクセスのコントロールを洗練化
    • 誰がアクセスできるか、誰が情報を得てるかを分析と把握をかんたんにしていく流れ
  • 反オープン化の流れへの反応としてプロトコル開発が進められてる
    • snsが提供してる機能を自由に使えるようにするため
    • 新しいプロトコル、新しい情報分散化のしくみ
    • プロジェクト乱立。どれもまだ成功してない
    • nodeもこうしたプロジェクトでも使える道具になるはず
      • 低レベルtcp/ipアプリケーションが作れるnode
  • nodeという言葉の由来
    • 色々なレベルでサーバー(node)がつながっていくさま
  • nodeでコマンドラインツール開発
    • CLIツール
    • nodeはCLIツールで必要になる機能もサポート
    • jsとnodeのエレガントなapiの組み合わせ
    • CLIツール開発でも活躍できるはず
  • nodeはDOMのエミュレーションが得意
    • サードパーティのモジュール(jsdom)がサポート
    • DOMのエミュレーションができると・・・開ける可能性
    • スクレイピング
      • JSDOMモジュールでDOMツリーエミュレート
      • jqueryでDOMツリー経由でデータ取得
    • テスト自動化
    • zombie.js
    • headlessブラウザ搭載の自動テスティング
  • 紹介しておきたいCLIツール

おわりに

  • 次章以降
    • アプリ開発の基礎
    • asyncプログラミング習得のコツ
    • フレームワークをフル活用したアプリ開発
    • tcp/ipサーバ開発
    • CLIツール
  • 次章
    • 開発環境作り
    • インストール:node本体、nodeモジュール