一.mongoDB中的連接池
剛上手MongoDB,在做應用時,受以前使用關係型數據庫的影響,會考慮數據庫連接池的問題!
關係型數據庫中,我們做連接池無非就是事先建立好N個連接(connection),並構建成一個連接池(connection pool),提供去連接和歸還連接等操作。
而在MongoDB中,我們先來看看怎麼進行操作,以insert爲例:
Mongo
m = new Mongo(
"localhost" ,
27017 ); DB
db = m.getDB( "mydb" ); //get
collection DBCollection
coll = db.getCollection( "testCollection" ) //insert BasicDBObject
doc = new BasicDBObject(); ... coll.insert(doc); [僞代碼] |
如果套用以前的經驗,可能會想偏,引用官方文檔的一句話可能會豁然開朗。
Note: The Mongo object instance actually represents a pool of connections to the database; you will only need one object of class Mongo even with multiple threads. See the concurrency doc page for more information.
The Mongo class is designed to be thread safe and shared among threads. Typically you create only 1 instance for a given DB cluster and use it across your app. If for some reason you decide to create many mongo intances, note that:
- all resource usage limits (max connections, etc) apply per mongo instance
- to dispose of an instance, make sure you call mongo.close() to clean up resources
mongo實例其實已經是一個現成的連接池了,而且線程安全。這個內置的連接池默認初始了10個連接,每一個操作(增刪改查等)都會獲取一個連接,執行操作後釋放連接。
二.連接池的重要參數
內置連接池有多個重要參數,分別是:
- connectionsPerHost:每個主機的連接數
- threadsAllowedToBlockForConnectionMultiplier:線程隊列數,它以上面connectionsPerHost值相乘的結果就是線程隊列最大值。如果連接線程排滿了隊列就會拋出“Out of semaphores to get db”錯誤。
- maxWaitTime:最大等待連接的線程阻塞時間
- connectTimeout:連接超時的毫秒。0是默認和無限
- socketTimeout:socket超時。0是默認和無限
- autoConnectRetry:這個控制是否在一個連接時,系統會自動重試
其設置方式如下:
MongoOptions
opt = mongo.getMongoOptions(); opt.connectionsPerHost
= 10 ; //poolsize opt.threadsAllowedToBlockForConnectionMultiplier
= 10 ; //其他參數類似 |
詳情參考mongoDB API:
Field Summary | |
---|---|
boolean |
autoConnectRetry If true, the driver will keep trying to connect to the same server in case that the socket cannot be established. |
int |
connectionsPerHost The maximum number of connections allowed per host for this Mongo instance. |
int |
connectTimeout The connection timeout in milliseconds. |
DBDecoderFactory |
dbDecoderFactory Override the DBCallback factory. |
DBEncoderFactory |
dbEncoderFactory Override the encoding factory. |
String |
description The description for Mongo instances created with these options. |
boolean |
fsync The "fsync" value of the global WriteConcern. |
boolean |
j The "j" value of the global WriteConcern. |
long |
maxAutoConnectRetryTime The maximum amount of time in MS to spend retrying to open connection to the same server. |
int |
maxWaitTime The maximum wait time in ms that a thread may wait for a connection to become available. |
boolean |
safe If true the driver will use a WriteConcern of WriteConcern.SAFE for all operations. |
boolean |
slaveOk Deprecated. Replaced in MongoDB 2.0/Java Driver 2.7 with ReadPreference.SECONDARY |
SocketFactory |
socketFactory sets the socket factory for creating sockets to mongod Default is SocketFactory.getDefault() |
boolean |
socketKeepAlive This flag controls the socket keep alive feature that keeps a connection alive through firewalls Socket.setKeepAlive(boolean) Default
is false. |
int |
socketTimeout The socket timeout in milliseconds It is used for I/O socket read and write operations Socket.setSoTimeout(int) Default
is 0 and means no timeout. |
int |
threadsAllowedToBlockForConnectionMultiplier this multiplier, multiplied with the connectionsPerHost setting, gives the maximum number of threads that may be waiting for a connection to become available from the pool. |
int |
w The "w" value of the global WriteConcern. |
int |
wtimeout The "wtimeout" value of the global WriteConcern. |
三.連接池實踐
package com.bts.dao.mongodb; import java.net.UnknownHostException; import com.bts.util.ConfTool; import com.mongodb.DB; import com.mongodb.Mongo; import com.mongodb.MongoException; import com.mongodb.MongoOptions; /** *
@author huangfox *
@data 2012-4-1 *
@email [email protected] *
@desc */ public class MongoManager
{ private static Mongo
mongo = null ; private MongoManager()
{ } /** *
根據名稱獲取DB,相當於是連接 *
*
@param dbName *
@return */ public static DB
getDB(String dbName) { if (mongo
== null )
{ //
初始化 init(); } return mongo.getDB(dbName); } /** *
初始化連接池,設置參數。 */ private static void init()
{ String
confFilePath = "" ; ConfTool
conf = new ConfTool(confFilePath); String
host = conf.getValue( "host" ); //
主機名 int port
= new Integer(conf.getValue( "port" )); //
端口 int poolSize
= new Integer(conf.getValue( "poolSize" )); //
連接數量 int blockSize
= new Integer(conf.getValue( "blockSize" ));
//
等待隊列長度 //
其他參數根據實際情況進行添加 try { mongo
= new Mongo(host,
port); MongoOptions
opt = mongo.getMongoOptions(); opt.connectionsPerHost
= poolSize; opt.threadsAllowedToBlockForConnectionMultiplier
= blockSize; }
catch (UnknownHostException
e) { //
log error }
catch (MongoException
e) { //
log error } } } |