Upgrade to Pro — share decks privately, control downloads, hide ads and more …

おまいらちゃんとリソース解放してますか / Remember to close resources!

shimataro
November 23, 2018

おまいらちゃんとリソース解放してますか / Remember to close resources!

東京Node学園祭2018の発表資料です
https://nodefest.jp/2018/

shimataro

November 23, 2018
Tweet

More Decks by shimataro

Other Decks in Technology

Transcript

  1. ⾃⼰紹介 ⾃⼰紹介 / / / ウェブリオ株式会社所属(京都) サーバサイド / インフラエンジニア 趣味は⼿品

    ⼿品業界→Web 業界 最近は ⼿打ちうどん にハマりかけてます ⼩⽥島 太郎 shimataro@GitHub odashima.taro@Facebook shimataro999@Twitter
  2. この発表について この発表について 対象 Node.js で Web アプリ を作っている⼈ 他の⾔語からの転⼊⽣ 特に

    リクエストごとにプロセスやメモリ空間が 独⽴している世界 からの来訪者(e.g., PHP ) 技術レベル: 中級 ↓スライドはこちら↓ https://speakerdeck.com/shimataro https://shimataro.github.io/slides/
  3. 1. グローバルオブジェクト 1. グローバルオブジェクト 利点 リソースは最⼩限 毎回確保する必要がないので⾼速 ⽋点 切断時の再接続処理が必要 瞬断

    MySQL では8 時間アイドル状態だと切断される トランザクションが他のリクエストを巻き込む 開発時は気づきにくい
  4. 2. 都度確保・都度解放 2. 都度確保・都度解放 必要なときに確保、不要になったら解放 const mysql = require("mysql"); const

    pool = mysql.createPool(...); function someFunc() { try { const connection = pool.getConnection(); // 必要になったら確保 ... // 何か処理 } finally { connection.release(); // 使い終わったら解放 } }
  5. 3. リクエスト内で使いまわす 3. リクエスト内で使いまわす リクエストオブジェクトにリソースを関連付け、この リソースを使いまわす (もしくはContinuation Local Storage を使⽤)

    const mysql = require("mysql"); const pool = mysql.createPool(...); function getConnection(req) { if(req.connection === undefined) { // req にリソースを関連付ける req.connection = pool.getConnection(); } return req.connection; }
  6. こうしとけ こうしとけ 3 箇所で解放 特に最後は⼤事(F5 連打対策) function middleware(req, res, next)

    { // Express.js のミドルウェア req.connection = ...; res .on("finish", () => { req.connection.release(); // 正常完了時 }) .on("close", () => { req.connection.release(); // 異常終了時(通信切断) }); if (res.socket.destroyed) { // すでに通信が切断されていた(イベントが発⽣しない) req.connection.release(); } }
  7. 簡単な⽅法 簡単な⽅法 on-finished パッケージを使うと楽 https://www.npmjs.com/package/on- nished const onFinished = require("on-finished");

    function middleware(req, res, next) { // Express.js のミドルウェア req.connection = ...; onFinished(res, () => { req.connection.release(); // ここで解放するだけ! }); }
  8. 関⻄でもNODE 学園! 関⻄でもNODE 学園! 東⻄で盛り上げていきましょう! 関⻄Node 学園 梅⽥キャンパス 1 時限⽬(04/20

    ) 関⻄Node 学園 梅⽥キャンパス 2 時限⽬(07/05 ) 関⻄Node 学園 3 時限⽬(08/03 ) 関⻄Node 学園 4 時限⽬(11/02 )