星期六, 11月 17, 2012

Node.js mysql connection pool

Node.js 中,我常用的 mysql module 大概是 node-mysql 了吧,但是因為想要盡量避免太多連線的建立,以前會在 module 中戶傳連線的物件,但又發現會有 timeout 的問題,這部分 node-mysql 的處理方式並不是很好需要重建連線,但是重建連線以後除非又要再把連線的物件傳到每個 module 不然無法使用。 另一方面,node-mysql 本身的 query 是 serial 的,人一多的時候若整個 application 只存在一個連線其實是不夠的,但以我以前的做法,多個連線會變成非常複雜。 於是我翻到了 node-mysql 首頁的最下面 TODO:

  • Prepared statements
  • setTimeout() for Connection / Query
  • connection pooling
  • ...
想一想,做一個共用的 connection pool 的話應該就能免去一些不必要的連線建立,同時也能在不同 module 中共用連線,又能達到多個 query 同時處理(用多個 connection 達到)的效果。以下是我透過 generic-pool 做出來的 mysql_pool.iced
mysql = require('mysql')
config = require __dirname + '/../config'

poolFactory = require 'generic-pool'
module.exports = poolFactory.Pool {
        name: 'mysql'
        create: (callback)->
                conn = mysql.createConnection {
                        host : 'localhost',
                        user :config.dbuser,
                        password : config.dbpass,
                }
                conn.query 'use ' + config.dbname
                callback(null, conn)
                return
        destroy: (conn)->
                conn.end()
                return
        max: 10
        idleTimeoutMillis: 30000
}
然後將這個 module 放到 node_modules 底下(方便各個 module require),因為 node.js 載入 module 的特性,同個位置的 module (基本上)會被 cache 起來,所以所有用到 pool 的地方都會從同一個 connection pool 來取得/試放連線,達到共用連線的目的。 這邊我建完 connection 先下了 use 的 query 再回傳,理論上應該要等 query 返回再回傳,但因為前面講過 node-mysql 是 serial 的所以沒關係(但以後可能會需要改就是了)..

沒有留言: