プロセスをしょうもないErrorで落とさないように頑張る

77 views
0 views

Published on

Node学園 22限目の発表資料です

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
77
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • * すでにQiitaや毛色の違うイベントで発表済みのネタなんでもしかしたら知っているかも
    * Node.jsでサーバやワーカをつくっている
    * 大量のコネクションをもつNode.jsサーバでのエラー処理が難しいということをここ1ヶ月くらいで考えていたので、自分なりにまとめてみた
  • Nede.jsはシングルプロセスシングルスレッドで稼働するイベントループモデルの実行環境となっています。
    図のように、待ちが発生する処理をイベントループに積んでタスクを順次実行していくのでシングルスレッドでも遅くなることがないと言われています。
    逆に待つ処理を入れてしまうのはよくないやり方です。
  • エラー処理もJavaとかPythonと比べると異なるやり方をとっていて、非同期I/O処理時のエラーは図のようにイベントのコールバックとして受け取ったり、ライブラリだとエラーオブジェクトとして受け取ったりします。
    同期処理だとこれは他の言語でよくあるthrow,try-catchのやり方になります。
  • 実際にNode.jsのアプリケーションを運用していて、難しいなーと思った事案をお話させてくだい。
    図のようにWebSocketのクライアントとサーバがあり、コネクションが長時間保持されています。
    \Nodeのイベントループには、それぞれのクライアントのためのタスクが積まれており、処理が終わったらクライアントへデータを送信するような構成になっています。
  • こういう場合、イベントループ中でやっていた処理中で想定外のエラーが発生すると
  • Node.jsではプロセスごと再起動する、というやり方になります。イベントループに積まれている未処理のタスクは実行しないまま終了してしまうということになります。
    サーバに接続しているクライアントはすべて切断されてしまいます。
    実際に、私が運用しているNodeアプリケーションの内部でつかっているライブラリの例外でこういうことが発生して障害につながった例もあります。

    NodeのuncaughtExceptionというイベントで想定外の例外を検知して無理やり回復できなくもないですが、それは安全に回復できないため推奨されていません。
  • 例えば、このようにPromise.catchしていても、catchのなかでエラーが投げられると、Promiseは何もしてくれません。
    これはunhandledRejectionイベントをみることで想定外のエラーが発生したときも最悪ログ出力しておけばあとで気づいて修正することができます。
    逆に、unhandledRejectionをみていないとバグに気づかないまま放置ということになりかねないと思います。
  • プロセスをしょうもないErrorで落とさないように頑張る

    1. 1. • • •
    2. 2. • • • •
    3. 3. • • • •
    4. 4. • • • •
    5. 5. • • •
    6. 6. http.get('http://www.google.com/index.html', (res) => { console.log(`Got response: ${res.statusCode}`); // consume response body res.resume(); }).on('error', (e) => { console.log(`Got error: ${e.message}`); }); app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); function myFunc() { throw new Error(“Error”); } try { myFunc(); } catch(err) { // handle err }
    7. 7.
    8. 8.
    9. 9. • •
    10. 10. • • •
    11. 11. • • • •
    12. 12.
    13. 13. • • • •
    14. 14. • • • •
    15. 15. • • •
    16. 16. • • • •

    ×