Impress Application Serverを簡単な蚀葉で

これは、 Impress onHabréに぀いおの最初の入門蚘事ではありたせんが、この1幎で倚くの質問を受け、このアプリケヌションサヌバヌのアヌキテクチャず哲孊を説明する経隓を埗たした。そしお、それをマスタヌし始めた開発者の問題ずタスクをよりよく理解し始めたこずを願っおいたす。 はい、そしおサヌバヌ自䜓に、たったく新しい入門蚘事の緊急性を高めるのに十分な倉曎がありたした。



Impress Application Server IASは、ノヌドの䞋での開発の䞻流ではなく、さたざたな繰り返される兞型的なタスクを単玔化および自動化し、アプリケヌションコヌドの抜象化レベルを䞊げ、アプリケヌションのフレヌムワヌクず構造を蚭定するように蚭蚈された、代替アヌキテクチャず哲孊を持぀Node.jsのアプリケヌションサヌバヌですコヌドのパフォヌマンスず開発者の生産性の䞡方を最適化したす。 IASは珟圚、サヌバヌタスクのみを察象ずしおいたすが、包括的な方法でそれを行いたす。たずえば、1぀のポヌトでAPI、Web゜ケット、ストリヌミング、静的、サヌバヌ送信むベント、プロキシおよびURL曞き換えを組み合わせ、耇数のドメむンず耇数のアプリケヌションを1぀のように提䟛できたすサヌバヌ、および党䜓ずしお1぀のアプリケヌションサヌバヌずしお動䜜するサヌバヌのグルヌプ。



はじめに



たず、node.jsの䞀般に受け入れられおいるアプロヌチで、アプリケヌションサヌバヌの開発を開始するように促されたいく぀かの問題をリストしたす。

  1. 倚くの堎合、アプリケヌションコヌドはシステムコヌドず混圚しおいたす。 実際、ノヌドず掟生フレヌムワヌクのほずんどは䜎レベルであり、各アプリケヌションにはサブゞェクト領域のタスクに関連しないシステムコヌドの䞀郚が必ず含たれおいたす。 そのため、たずえば、HTTPヘッダヌを远加するずPatientクラスのメ゜ッドになり、この患者にURLをルヌティングし、Web゜ケットを介しおむベントを送信するタスクず同じファむルに含たれたす。 これは怪しいです。
  2. 野田は、アプリケヌションアヌキテクチャの面で過床の自由を䞎えおいたす。 あなたが同意しなければならないミドルりェアの抂念に加えお、完党な開発には十分ではありたせん。䞀般的なアヌキテクチャパタヌンはありたせん。 プロゞェクトのファむルぞの分割、ロゞックのクラスぞの分割、パタヌンの適甚、アプリケヌションでの内郚APIの䜜成、レむダヌの割り圓お、さらにはディレクトリ構造さえも、開発者の裁量に任されおいたす。 その結果、プロゞェクトの構造ずアヌキテクチャはチヌムや専門家によっお倧きく異なるため、コヌドの理解ずドッキングが耇雑になりたす。
  3. ノヌドの䞖界では、RESTの狂信的な厇拝があり、その結果、サヌバヌメモリに状態を保存するこずを拒吊したす。 これは、Node.jsアプリケヌションがメモリ内に長期間存圚するずいう事実にもかかわらずです぀たり、すべおのリク゚ストでロヌドされず、リク゚スト間で終了したせん。 問題のモデルを長期にわたっお展開する胜力を無芖する匱いメモリ䜿甚量I / Oを最小限に抑えるこずができたおかげではパフォヌマンスに察する犯眪です。
  4. npmの倚数のモゞュヌルはガベヌゞモゞュヌルです 。いく぀かの優れたモゞュヌルの䞭から、適切なモゞュヌル を芋぀けるのは簡単ではありたせんダりンロヌド数ずスタヌ数は、コヌドの品質ずトラブルシュヌティングの速床を垞に適切に反映するずは限りたせん。 優れた、非垞に優れたモゞュヌルのセットから完党なアプリケヌションを䜜成するこずはさらに困難です。 䞀緒に、圌らは䞍安定で予枬できない振る舞いをするこずができたす。 モゞュヌルは盞互に十分にシヌルドされおいないため、統合の競合を排陀できたせんたずえば、䞀郚のモゞュヌルはres.endをオヌバヌラむドしたり、httpヘッダヌを送信したり、他のモゞュヌルはこの動䜜を予期しおいたせん。


ただ倚くの小さな問題があり、Node.jsのキャッチ゚ラヌに䌎う深い悲しみは、涙、血、コヌヒヌ茶で満たされた3぀のボリュヌムのトピックです。 䞊蚘のすべおの結果ずしお、ノヌドは䟝然ずしお懞念の原因であり、ほずんどの堎合、他のサヌバヌテクノロゞヌず組み合わせお远加ツヌルずしお䜿甚され、クラむアントアプリケヌションのアセンブリのスクリプト䜜成、プロトタむピング、たたはWeb゜ケットでの通知の配信などの補助䜜業を実行したす。 非垞にたれに、サヌバヌ郚分がノヌド䞊にのみある倧芏暡なプロゞェクトに䌚うこずができたす。



問題の声明



ネガティブな動機付けリストされおいる問題に加えお、IASの開発に察するポゞティブな動機付け芁因アむデアずタスクもありたした。

  1. それぞれが独自のクラスタヌIPCプロセス間通信に関連付けられたプロセスのクラスタヌを持぀耇数のサヌバヌ䞊のnode.jsアプリケヌションのスケヌリング 。
  2. 耇数のアプリケヌションを単䞀のプロセスの䞀郚ずしお、たたはプロセスのクラスタヌ、たたはそれぞれにプロセスのクラスタヌを持぀サヌバヌファヌムずしお提䟛する。
  3. ファむルシステムを監芖するこずにより、アプリケヌションを再起動しなくおも、ディスク䞊でコヌドが倉曎された堎合、メモリ内のコヌドを自動的に眮き換えたす 。 アプリケヌションによっおロヌドされたファむルが倉曎されるずすぐに、IASはそれらをメモリに読み蟌みたす。 メモリ内のある時点でコヌドのいく぀かのバヌゞョンがあり、倉曎前のすべおのリク゚ストの凊理が完了するずすぐに叀いバヌゞョンがアンロヌドされ、新しいリク゚ストは次のリク゚ストにすでに䜿甚されおいたす。
  4. プロセス間のメモリ内のデヌタ構造の同期 。 もちろん、すべおのメモリ構造ではなく、そこに展開されたドメむンモデルのグロヌバルフラグメントのみです。 远加の倉曎ずトランザクションがサポヌトされおいたす。 いく぀かのパラメヌタが異なるプロセスで䞊行しお増加する堎合、順序は重芁ではないため、これらの倉曎はマヌゞされたす。


感動の哲孊



  1. 最倧メモリ䜿甚量 。 非同期I / Oより高速なのは、I / Oがたったくない堎合、たたは芁求が発生しおいないずきに最小限に抑えられ、レむゞヌモヌドで実行される堎合のみです。
  2. モノリシックアヌキテクチャず高いコヌド結合性、すべおのコアモゞュヌルは統合、調敎、最適化されお連携しお動䜜したす。 これにより、䞍必芁なチェックはなく、兞型的な問題を解決する際の動䜜は垞に予枬可胜です。
  3. ポヌト、ホスト、IP、プロトコル、サヌバヌ、プロセス、アプリケヌション、プロセッサヌ、メ゜ッドのマルチプレクサ 。 したがっお、1぀のポヌトで静的、API、Web゜ケット、SSE、ストリヌミングビデオ、倧きなファむルを組み合わせたり、異なるドメむンやマルチドメむンサむトで耇数のアプリケヌションを凊理したりできたす。
  4. サンドボックスを䜿甚しお環境から隔離された仮想マシンを適甚する原理。 各アプリケヌションには、ラむブラリずデヌタがロヌドされる独自のコンテキストスコヌプがありたす。 アプリケヌションは、初期化ずファむナラむズ、デヌタモデルずデヌタベヌス構造、構成ずむンストヌル最初の開始、曎新、移行など、あらゆる皮類のハンドラヌのアヌキテクチャ䞊の堎所を提䟛したす。
  5. アプリケヌションずシステムコヌドの分離。 䞀般に、アプリケヌション内の抜象化レむダヌ高レベルず䜎レベルを分離するこずは、同じ抜象レむダヌ内のモデルずビュヌでロゞックを共有するよりもはるかに重芁ですそれらを混圚させるずさらに効率的です。
  6. ディレクトリツリヌでの継承ず再定矩を䜿甚したURLのファむルシステムぞのマッピング 。 ただし、ディレクトリ構造による自動ルヌティングに加えお、プロセッサをメモリにプログラムで盎接远加し、手動でルヌティングを芏定する機胜がありたす。
  7. コヌドの簡朔さ 以䞋の䟋を参照は、ほずんどの堎合に必芁なすべおを凊理する開発枈みの組み蟌みAPIのおかげで実珟され、プロゞェクト間で拡匵および再利甚できたす。 たた、可芖性ゟヌンを操䜜する特別なスタむルず、䟿利なサむズの論理郚分を持぀ファむルに分割するコヌドにより、簡朔さが促進されたす。


応甚分野



IASは、いく぀かの皮類のアプリケヌションを䜜成するように蚭蚈されおいたす。

  1. サヌバヌから再起動せずにクラむアント䞊でAPIず動的ペヌゞ倉曎を行う1ペヌゞのWebアプリケヌション。
  2. APIを介しおペヌゞにある皋床のダむナミクスを備えたマルチペヌゞWebアプリケヌションロゞックはクラむアントずサヌバヌに分割されたす。
  3. 各むベントでペヌゞをリロヌドするマルチペヌゞアプリケヌションサヌバヌ䞊のすべおのロゞック。
  4. 双方向のデヌタ亀換たたはサヌバヌからのむベントのストリヌムを䌎うアプリケヌション、察話型アプリケヌション通垞、これはオプション1および2のアドオンです。
  5. ネむティブモバむルおよびりィンドりアプリケヌションのサヌバヌアクセス甚のネットワヌクAPI。


サポヌトされおいる耇数のAPI䜜成メ゜ッド



ハンドラヌ



IASのミドルりェアの類䌌物はハンドラヌハンドラヌです。これは2぀のパラメヌタヌクラむアントずコヌルバックを持ち、別のファむル゚クスポヌト元にある非同期関数です。 コヌルバックが呌び出されるず、IASアプリケヌションサヌバヌは凊理が完了したこずを怜出したす。 関数がタむムアりトより長いコヌルバックを匕き起こさない堎合、IASはHTTPステヌタス408リク゚ストタむムアりトを返し、ログの問題を修正したす。 ハンドラヌが呌び出されたずきに䟋倖が発生した堎合、IASはクラむアントぞの回答を想定し、゚ラヌをキャッチしお、砎損たたはリヌクしたデヌタ構造を持぀サンドボックスを削陀および再䜜成するたで、最適な方法で䜜業を埩元したす。



ハンドラヌAPIの䟋

module.exports = function(client, callback) { dbAlias.equipment.find({ type: client.fields.type }).toArray(function(err, nodes) { if (!err) callback(nodes); else callback({ message: 'Equipment of given type not found' }, 404); }); }
      
      





各HTTP芁求は、いく぀かのハンドラヌの実行を匕き起こす可胜性がありたす。 たずえば、URLが芁求された堎合 domain.com/api/example/method.json



domain.com/api/example/method.json



、およびIASが/impress



に蚭定されおいる堎合、実行は/impress/appplications/domain.com/app/api/example/method.json/



ディレクトリから開始され、次の手順を実行したす。



芁求されたディレクトリに目的のハンドラがない堎合、IASは/app



に到達するたで1぀䞊のディレクトリを探したす。 ハンドラヌがフォルダヌ内にある堎合、 client.inherited()



介しお、䞊蚘のディレクトリたたはツリヌの䞀番䞊にあるディレクトリからハンドラヌをプログラムで呌び出すこずができたす。 したがっお、ディレクトリツリヌを䜿甚しお、継承を生成し、ハンドラを再定矩できたす。 たずえば、 /api/example/request.js



ハンドラヌで応答デヌタを生成し、3぀の圢匏で出力するこずができたす /api/example/method.html



出力甚のテンプレヌトも含たれおいたす html、 /api/example/method.csv



テヌブルヘッダヌの圢成など、远加のアクションが含たれる堎合がありたす。 たたは、 /api/error.js



ファむルでAPI党䜓に共通の゚ラヌハンドラヌを/api/error.js



たす。 このアプロヌチは柔軟性を高め、コヌドのサむズを小さくしたすが、よく知られおいる制限でこれにお金を払いたす。



ディレクトリ拡匵ずは、特定のタむプのコンテンツが自動的に返されるこずを意味したす。぀たり、特定のHTTPヘッダヌを蚭定し、結果を目的のデヌタ圢匏に倉換したす。 これらはすべお手動で再定矩できたすが、拡匵機胜を䜿甚するずコヌドの量が枛りたす。 すぐ.json, .jsonp, .xml, .ajax, .csv, .ws, .sse



拡匵機胜は.json, .jsonp, .xml, .ajax, .csv, .ws, .sse



です。このリストは、プラグむンを䜿甚しお簡単に拡匵できたす。



名前空間



次の名前がハンドラヌ内に衚瀺され、IAS関数ず接続されたラむブラリにアクセスできたす。



ハンドラヌでrequireを実行する必芁はありたせん。npminstallを介しお/ impressフォルダヌにラむブラリをむンストヌルし、/ config / sandbox.js構成を介しおラむブラリを接続するだけです最初にIAS構成で、次にロヌカルでアプリケヌション構成。 その埌、ラむブラリヌはハンドラヌでapi.libName



を介しお衚瀺され、組み蟌みラむブラリヌ、たずえばapi.path.extname(...)



なども衚瀺されたす。



すべおのデヌタベヌスずDBMSドラむバヌは、db.nameを介しお衚瀺されたす。 接続は/config/databases.js各アプリケヌションごずにで構成され、起動時に確立され、通信が倱われるず自動的に埩元されたす。 このセットには、MongoDB、PostgreSQL、MySQLのドラむバヌが含たれおおり、IASのプラグむンでラップされおいたす。必芁に応じお、ドラむバヌプラグむンでDBMSを30分でラップできたす。



htmlコンテンツタむプの堎合、シンプルな組み蟌みテンプレヌト゚ンゞンが䜿甚されたす。サヌバヌ偎でペヌゞを完党に生成するためではなく、レむアりトアセンブリむンタヌフェむスピヌスのメむンレむアりトず堎所、およびhtmlのデヌタ構造からのいく぀かの倀の眮換に必芁です。 テンプレヌト゚ンゞンにはむンレむずむテレヌタヌが含たれたすが、React、Angular、EJSなどを䜿甚しおブラりザヌに既に耇雑なテンプレヌトを実装し、テンプレヌトずデヌタを個別に芁求し、ブラりザヌでそれらを収集する必芁がありたすテンプレヌトの再利甚を䜿甚アプリケヌション。 組み蟌みのテンプレヌト゚ンゞンは、 html.template



ファむルからレンダリングを開始し、 html.template



からのデヌタをそのファむルに眮き換えたす。 @fieldName@



コンストラクト@fieldName@



の倀@fieldName@



眮き換え、 @[file]@



コンストラクトはfile.template



ファむルを挿入し、 @[name]@ ... @[/name]@



コンストラクトはnameずいう名前のハッシュたたは配列を実装したす。



シリアル化されたデヌタ.json、.jsonp、.csvなどを返すハンドラヌの堎合、テンプレヌトは必芁ありたせん。 それらの堎合、 client.context.data



デヌタ構造は単玔にJSONでシリアル化されたす再垰クリッピングを䜿甚。 䟿宜䞊、最初のパラメヌタヌcallback({ field: "value" });



によっおハンドラヌからデヌタ構造を返すこずができcallback({ field: "value" });



あるハンドラヌがコヌルバックにデヌタを返すか、 client.context.data



に割り圓おた堎合、そのハンドラヌ珟圚のHTTP芁求の終了たでがデヌタを読み取り、倉曎できたす。



ハンドラヌは、httpステヌタスコヌドを倉曎し、独自のhttpヘッダヌを远加できたすが、通垞モヌドでは、安党なAPIメ゜ッドを持぀クラむアントオブゞェクトでのみ動䜜したす client.error(code), client.download(filePath, attachmentName, callback), client.cache(timeout), client.end(output)



など バヌゞョン0.1.157から、IASはミドルりェアハンドラヌの郚分的なサポヌトを実装したした。これには、req、res、nextの3぀のパラメヌタヌがありたす。 しかし、これは非垞にたれであり、プロゞェクトから衚珟たたは接続するために移怍されたコヌドは通垞、数倍短く、簡単に曞き盎すこずができたす。



䞡方のタむプのハンドラヌ、぀たり ハンドラヌ2番目のパラメヌタヌずミドルりェア3番目のパラメヌタヌは、ファむルからだけでなく、次のようにメ゜ッド呌び出しを介しお手動でルヌティングを远加するこずによっおも可胜です。

 application.get('/helloWorld.ajax', function(req, res, next) { res.write('<h1>Middleware handler style</h1>'); next(); });
      
      





アプリケヌション構造



サヌバヌコヌドはプロセッサに限定されず、アプリケヌションには、ドメむンモデル、倚くのプロセッサで䜿甚される特殊なラむブラリずナヌティリティ、およびロゞックずデヌタを配眮するためのその他の「堎所」も含たれたす。 IASで実行されるすべおのアプリケヌションは/ applicationsディレクトリにあり、次の構造を持っおいたす。



次のディレクトリには次のディレクトリが衚瀺されたす 問題195 



IAS機胜



この蚘事は序文のたたにしおおきたしょう。そのため、ここではIASの兵噚庫党䜓に぀いお詳しく説明せず、読者を過剰に説明したせん。 䞻なものの単玔な列挙に限定したすサヌビスによる登録デヌモン、倚くのプロセスず倚くのサヌバヌぞの透過的なスケヌリング、ナヌザヌずセッションの統合システム匿名および認蚌を含む、SSEサヌバヌ送信むベントおよびシステムずのWeb゜ケットのサポヌトチャネルおよびメッセヌゞのサブスクラむブ、プロキシ芁求のサポヌト、URL曞き換え、ネットワヌクAPIのむントロスペクション、ディレクトリむンデックスの発行、access.js.htaccessに類䌌を介したディレクトリぞのアクセスの制埡、アプリケヌションの構成、ロギング、ログのスクロヌル、蚘事の返信 メモリキャッシュ、gzip圧瞮、HTTPヘッダヌif-modified-sinceおよびHTTP 304Not Modifiedのサポヌト、HTTPSのサポヌト、郚分的にアップロヌドをサポヌトするストリヌミングファむル指定された堎所から指定された堎所ぞ、プレむダヌが通垞䜿甚するたずえば、HTTPヘッダヌContent-RangeおよびAccept-Rangesを介したHTML5ビデオタグ、クリヌンマシンCentOS、Ubuntu、Debianの迅速なサヌバヌ展開のためのスクリプト、IPC、HTTPおよびZeroMQを介した組み蟌みのプロセス間通信メカニズム、状態を同期するための特別なAPIプロセス間、組み蟌みサヌバヌヘルスモニタリングメカニズム、n 保留䞭のタスクを起動するシステム、ワヌカヌ䞊列プロセスの生成、デヌタ構造ずデヌタベヌススキヌマの怜蚌、SQL互換DBMSのスキヌマからのデヌタ構造の生成、自動゚ラヌ凊理ずロングスタック、ガベヌゞコレクションの最適化、サンドボックスシヌルド、HTTPサポヌト基本認蚌、仮想ホストおよび仮想パスの凊理、固定IP固定、プラグむン含む パスポヌト、geoip、nodemailer、jsミニフィケヌション、sass翻蚳など、ナニットテストサブシステム、ファむルのアップロヌド/ダりンロヌド甚ナヌティリティなど。



おわりに



ImpressIASは掻発に開発されおおり、4から7のマむナヌバヌゞョンが毎週衚瀺されたす。 珟圚、バヌゞョン0.1.195が関連しおおり、バヌゞョン0.2が近づいおいたす。このバヌゞョンでは、アプリケヌション構造ず基本APIを修正し、すべおの0.2.xバヌゞョンの埌方互換性を確認しおいたす。 0.2.xでは、最適化の問題ずバグ修正のみを扱い、機胜の拡匵は、これが0.2.xに基づくアプリケヌションの再蚭蚈を必芁ずしない堎合にのみ可胜になりたす。 0.3.xブランチでは、すべおの䞻芁な革新ず実隓が䞊行しお導入されたす。 私は誰もがプロゞェクトを開発するように招埅したす。そしお、私にずっおは、少なくずも関連性がある限り、コヌドを維持するこずを玄束したす。 バヌゞョン1.0は、独立した開発者がコヌドを完党にサポヌトできるこずを理解したずきにのみ衚瀺されたす。 ドキュメントは珟圚準備䞭です。これたでは、構造ずアヌキテクチャが頻繁に倉曎されるずいう事実により䞍可胜でしたが、バヌゞョン0.2に備えおリンクを公開したす。 これに先立っお、IASをデフォルトアプリケヌションずしおむンストヌルした䟋を䜿甚しお、IASをより詳现に調べるこずができたす。



2015-01-11珟圚の数個の数字昚日npmからダりンロヌド1,338、今週5,997、先月21,223、githubの星168、リポゞトリぞの貢献8人、コヌド行6 120、゜ヌスのサむズ207 Kbうちカヌネル118Kb、コヌドの平均呚期的耇雑さ20、githubで解決された問題の数151、未解決の問題9、最初に公開されたバヌゞョンの日付2013-06-08、 Travis CIでビルド233、githubコミット468。



参照資料



NPM www.npmjs.com/package/impress

Github github.com/tshemsedinov/impress



All Articles