首先,使用新的 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 之類的
沒有留言:
張貼留言