顯示具有 coffee-script 標籤的文章。 顯示所有文章
顯示具有 coffee-script 標籤的文章。 顯示所有文章

2013年11月27日

Keep MongoDB connection in nodejs 筆記

因為是小 project 使用 native mongodb nodejs driver
首先,使用新的 MongoClient 取代 Db
雖然範例裡面都有乖乖 db.close() ,但是其實不需要這樣,
更好的方法是持續這個 mongodb connection ,並且讓需要 mongodb 的部分共用同一個 connection。
一開始我的寫法類似範例裡的方式
mongo = require '\mongodb' mongoClient = mongodb.MongoClient mongodbURI = 'mongodb://127.0.0.1:27017/test' route.get '/abc', (req, res) -> mongoClient.connect mongodbURI, (err, db) -> throw err if err db.collection('abc').insert({foo:'bar'}, (err, result) -> throw err if err console.log "succes insert abc" db.close() ) 這樣的配置 nginx - nodejs - mongodb 在第二天大量流量進來的時候會噴發
nginx: connect() failed (111: Connection refused) while connecting to upstream [Error: failed to connect to [localhost:27017]] 這個跟 localhost 或是 127.0.0.1 無關
由於 process 結束會自動斷掉 connection ,以下嘗試拿掉 db.close()
route.get '/abc', (req, res) -> mongoClient.connect mongodbURI, (err, db) -> throw err if err db.collection('abc').insert({foo:'bar'}, (err, result) -> throw err if err console.log "succes insert abc" ) 這樣 mongodb 會自動處理 mongo connection ,但是量大的時候依然會噴發 [initandlisten] connection accepted from 127.0.0.1:41822 #277824 (7998 connections now open) 失去 nginx - nodejs 可以處理 C10K problem 的優勢
嘗試改成一開始就建立 mongodb connection 並且不關閉,
使用mongodb 預設 maxPoolSize=5 mongoClient.connect mongodbURI, (err, db) -> throw err if err route.get '/abc', (req, res) -> db.collection('abc').insert({foo:'bar'}, (err, result) -> throw err if err console.log "succes insert abc" ) route.get '/def', (req, res) -> db.collection('def').insert({foo:'bar'}, (err, result) -> throw err if err console.log "succes insert def" ) 以上處理上千個併發沒問題, mongodb 會自動處理 connection pool,只需要依需求調整 maxPoolSize
實際上可以把 mongodb 提出來
mongo.coffee mongodb = require 'mongodb' mongoClient = mongodb.MongoClient mongodbURI = 'mongodb://127.0.0.1:27017/test' module.exports.init = (callback) -> mongoClient.connect mongodbURI, (err, db) -> console.log err if err console.log 'opened mongodb connection' callback(err, db)
server.coffee mongo.init (err, db) -> throw err if err ...
順代一提,Apache Benchmark ab test 連線數量多的時候連線數量並不準確,
像是 -n 1000 -c 10 可能實際上送了 1007 次 request 之類的