$30 off During Our Annual Pro Sale. View Details »

tfcon2022.pdf

kohta ito
May 14, 2022
1.3k

 tfcon2022.pdf

kohta ito

May 14, 2022
Tweet

Transcript

  1. 伊藤康太(@koh110)
    Node.js
    パフォーマンスチェックポイント
    1

    View Slide

  2. Node.js パフォーマンスチェックポイント
    Node.jsはフロントエンドと同じJavaScriptでバックエンドを記述
    できるメリットがあります。
    ですが、フロントエンドとバックエンドではパフォーマンス向上に
    必要な観点が異なります。
    本LTではパフォーマンスの観点でチェックするポイントを紹介し
    ます。

    View Slide

  3. Node.jsの特徴
    Node.jsを特徴づけるポイント

    非同期のイベント駆動形ランタイム

    Non Blocking I/Oとシングルスレッド
    V8(JavaScriptエンジン)+ libuv(非同期I/O)
    JavaScriptの世界とI/Oをつなぐためにイベントループがある
    パフォーマンスを低下させないために、イベントループを極力止め
    ない事が重要なポイント

    View Slide

  4. Node.js パフォーマンスチェックポイント
    1. 同期関数の利用がないか
    2. 巨大なJSONを扱っていないか(JSON.parse/JSON.stringify)
    3. 長いループがないか
    4. 最新のLTSを利用しているか
    5. 追加デプロイ先が自前サーバーの時

    cluster化しているか
    • ファイルディスクリプタの上限数が適切か

    View Slide

  5. 同期関数の利用がないか
    ~Syncなどの同期処理がリクエストのたびに
    実行されないかをチェック
    同期処理がリクエストのたびに実行されてい
    ないかを確認する
    抜き出せるものはサーバーの起動時にだけ
    通るように集約する
    非同期関数がある場合はそちらを利用する
    const fs = require('fs');
    app.get('/', (req, res) => {
    // ここで他の処理もストップしてしまう
    const html = fs.readFileSync('./index.html');
    res.status(200).send(html);
    });

    View Slide

  6. 巨大なJSONを扱っていないか
    JSON.parse/JSON.stringifyは同期処理
    できるだけ数を少なくなるようにする
    特にライブラリ内部で利用されていると気づきにくい
    JSONのサイズによってかかる時間も増加するため、サイズ
    を小さく保つことも重要
    APIレスポンスなどが運用の時間経過で大きくなりやすいの
    で注意する
    最大1MB以内程度を目安としている
    > JSON.parse('{"foo":"bar"}')
    { foo: 'bar' }
    > JSON.stringify({ foo: 'bar'})
    '{"foo":"bar"}'

    View Slide

  7. 長いループがないか
    ループ処理も基本的には同期処理
    1つのループが長くならないよう気を付ける
    運用の時間経過とともに長くなってしまう事がある
    ループが分割できないかを検討する
    またはStreamとして扱えないかを検討する
    (最近はAsyncIteratorが使えるのでStreamを最初に考える事が多い)

    View Slide

  8. 追加デプロイ先が自前サーバーの時
    サーバーを用意する時は次の設定を最初に確認する

    cluster化しているか

    ファイルディスクリプタの上限数が適切か
    CaaSやPaaSが増えて考慮しないことも増えた
    CaaSやPaaSはサーバーリソースを使い切るより、横に並べたほうがいい場合が多い

    View Slide

  9. cluster化しているか
    clusterを利用するとマルチコアを利用してシンプルにパ
    フォーマンスを向上できる
    簡単に言えばfork数分パフォーマンスがあがる
    CPUの張り付きを避けるために
    「CPU数/2」や「CPU数-1」までforkすることが多い
    const cluster = reuqire('cluster');
    if (cluster.isPrimary) {
    // ワーカープロセスを3つまでforkする
    for (let i = 0; i < 3; i++) {
    cluster.fork();
    }
    // ワーカープロセスが終了したら再度forkする
    cluster.on('exit', (worker, code, signal) => {
    cluster.fork();
    });
    } else {
    server.listen(3000, () => {
    console.log('Listening on', server.address());
    });
    }

    View Slide

  10. ファイルディスクリプタの上限数が適切か
    Node.jsはひとつのプロセスで多くのリクエストを受けるた
    め、1プロセスが大量のファイルを扱います。
    ファイルディスクリプタの上限値がデフォルト値だと足りなく
    なりがち
    十分大きな値となるよう設定する(`65535`など)
    $ ulimit -n
    # 全然足りない
    1024

    View Slide

  11. 最新のLTSを利用しているか
    Node.jsはV8というエンジンでJavaScriptを解釈し実行します
    V8のパフォーマンスはアプリのパフォーマンスに直結する
    V8はバージョンアップで大きく高速化されることも珍しくない
    (V8 blogを眺めるのがおすすめ)
    Node.jsのバージョンをあげないとV8の恩恵を受けられない
    なるべく最新のLTSに追従できるようにしておく

    View Slide

  12. Node.js パフォーマンスチェックポイント
    アプリケーションのパフォーマンスを保つためにチェックするポ
    イントについてまとめました
    実際の運用では計測しないとわからない事も多い
    これらパターンが起きてないかをまず確認すると原因を絞り込
    みやすいと思います

    View Slide

  13. ありがとうございました

    View Slide