Express(Node.js)のベストプラクティス
非同期関数のエラー処理
Nodeは非同期関数からエラーを返すために「error-firstコールバック」という規則を使用する
エラーが無いことを示す場合、引数はnull
Expressにおいては、next()関数を使用して、ミドルウェアアプリケーションを介してエラーを伝搬する
Expressにおけるエラー処理のアンチパターン
例外がイベントループまでたどり着いた場合に生成されるuncaughtExceptionイベントをlistenすること
uncaughtExceptionのイベントリスナーを追加すると、例外が発生したプロセスのデフォルトの動作が変更される
キャッチされない例外が発生した後にアプリケーションの実行が続行するのはよくない
プロセスの状態の信頼性を予測可能性が低くなる
正式に粗雑なものとして認められていて、コアから削除するための提案が出されている
domainの使用
このモジュールは本質的な問題を解決していない
try-catchの使用
同期コードで例外をキャッチするために使用できる
同期コードのみで機能する
Nodeプラットフォームは主に非同期的であるため、try-catchは多くの例外をキャッチしない
Promiseの使用
Promiseはthen()を使用する非同期コードブロックすべての例外を処理する
注意点
すべての非同期コードがPromiseを返す必要がある
特定のライブラリがPromiseを返さない場合は、Bluebird.promisifyAll()などのヘルパー関数を使用して、基本オブジェクトを変換する
イベントエミッターなどにより、例外がキャッチされないことがある。
環境/セットアップで処理する処理
NODE_ENV=productionとする
NODE_ENV=productionとしたときのExpressの動作
ビューテンプレートをキャッシュに入れる
CSS拡張から生成されたCSSファイルをキャッシュに入れる
詳細度の低いエラーメッセージを生成する
実働環境での設定
開発環境では対話シェル(exportや.bash_profile)を使用
実働環境ではOSのinitシステム(systemdやupstart)を使用する
アプリケーションの自動再起動
対策
アプリケーションが異常終了した場合にプロセスマネージャーを使用してそれらを再起動する
OSの異常終了時に、OSで提供されているinitシステムを使用してプロセスマネージャーを再起動する
Nodeアプリケーションは、キャッチされていない例外が発生すると異常終了する
例外処理をきちんとする = 異常終了するのを避ける
異常終了そのものが避けるべきことだが、起こってしまったときの対策はしておく
アプリケーションをクラスタで実行する
CPUの1コアごとに1つのインスタンスを実行するのが理想
アプリケーションインスタンスは別々のインスタンスとして実行されるので、メモリを共有しない
Redisなどのメモリー内のデータストアを使用して、セッション関連のデータと状態を保持できる
ーカー・プロセスが異常終了するたびに、必ず、イベントをログに記録して、cluster.fork() を使用して新規プロセスを作成する