MongoDB的连接对象是DBPort,所以可以从DBPortPool对象看起,构造函数如下:
DBPortPool( ServerAddress addr , MongoOptions options ){
super( "DBPortPool-" + addr.toString() + ", options = " + options.toString() ,options.connectionsPerHost );
_options =options;
_addr = addr;
_waitingSem = new Semaphore( _options.connectionsPerHost * _options.threadsAllowedToBlockForConnectionMultiplier );
}
可以看出java-driver会为每个ServerAddress创建一个连接池。也是因为MongoDB是在驱动中设置高可用的,可以配置多个MongoS或MongoD的连接。_waitingSem是个很有意思的信号量,他是由connectionsPerHost和threadsAllowedToBlockForConnectionMultiplier相乘得出的,在后面来分析他的用法。
DBPortPool的父类是SimplePool,再来看从父类的构造函数可以看出:
publicSimplePool(String name, int size){
_name = name;
_size = size;
_sem = new Semaphore(size);
}
其中,size就是connectionsPerHost,SimplePool使用connectionsPerHost创建了一个信号量_sem,可以通过_sem在SimplePool中的使用方式来分析一下连接的创建策略。
SimplePool中,通过下面方法申请获取连接的许可证,
privatebooleanpermitAcquired(finallong waitTime) throws InterruptedException {
if(waitTime > 0) {
return_sem.tryAcquire(waitTime, TimeUnit.MILLISECONDS);
} elseif (waitTime < 0) {
_sem.acquire();
returntrue;
} else {
return_sem.tryAcquire();
}
}
获取这个许可有一个等待时间的策略,如果waitTime为0,那么如果可以获取连接就立即返回true,如果不能获取连接就立即返回false;如果设置了waitTime为正数,会等待waitTime毫秒,如果这段时间仍然没有连接可以使用就返回false;如果waitTime就负数,那么会一直等待直到获得许可为止。
这在被调用方法不能设置超时时间的时候,在调用方法中设置超时时间的方法。
这也是一个平衡线程利用率的策略,在一个有限且使用率高的线程池中,让一个线程等待时间过长无疑是一种浪费,MongoDB使用阻塞信号量配置等待时间的方法,配置线程的释放策略。
这个方法是在获取DBPort对象时被调用的,用来申请获取连接的许可:
public T get(long waitTime) throws InterruptedException {
if(!permitAcquired(waitTime)) {
returnnull;
}
//获取连接的方法略……
// t =createNewAndReleasePermitIfFailure();
}
SimplePool是一个获取池对象的基类方法,createNewAndReleasePermitIfFailure方法会调用子类的createNew方法来创建具体对象。然后再看看这个信号量什么时候被释放:
private TcreateNewAndReleasePermitIfFailure() {
try {
T newMember = createNew();
if(newMember == null) {
thrownew IllegalStateException("null pool members are not allowed");
}
returnnewMember;
} catch(RuntimeException e) {
_sem.release();
throw e;
} catch (Errore) {
_sem.release();
throw e;
}
}
可见,在连接创建失败的时候会释放这个信号量。
publicvoid done( T t ){
synchronized( this ) {
if (_closed) {
cleanup(t);
return;
}
// 释放连接方法略……
}
_sem.release();
}
还有就是连接使用完毕,要调用done释放连接,信号量就会被恢复。
从上可知。connectionPerHost是单个Mongo服务连接地址的连接池数量,连接都被占用的获取连接等待时间是可设置的,由MongoClientOptions.maxWaitTime参数决定,默认时间是两分钟,可以通过减少这个值来提升线程利用率。
再来看看_waitingSem这个信号量的用法,他只在一个方法中被使用了:
public DBPort get() {
DBPort port = null;
if ( ! _waitingSem.tryAcquire() )
thrownew SemaphoresOut(_options.connectionsPerHost * _options.threadsAllowedToBlockForConnectionMultiplier);
try {
port = get( _options.maxWaitTime );
} catch(InterruptedException e) {
thrownew MongoInterruptedException(e);
} finally {
_waitingSem.release();
}
if ( port== null )
thrownew ConnectionWaitTimeOut( _options.maxWaitTime );
port._lastThread =System.identityHashCode(Thread.currentThread());
return port;
}
_waitingSem值的大小是连接池大小乘以一个常数(>=1),这个信号量在获取连接动作之前取得,在获取连接后马上释放,而不用等待连接被放回线程池,说明在线程池为空的情况下,最多可以有(connectionsPerHost* threadsAllowedToBlockForConnectionMultiplier)多个线程被阻塞在
port = get(_options.maxWaitTime)这段代码处。超过这个数就会抛异常,告诉后面的线程不用等了。所以这是一个等待获取连接的队列,队列的长度就是连接池大小乘以一个常数。如果线程池数量有限,而又允许有一定数据损失的场景下,可以将threadsAllowedToBlockForConnectionMultiplier值调小,比如写日志。像MongoDB这种周期性从内存向磁盘写入数据的情况,默认是每60秒写如一次数据,如果内存不够大,可能会在客户端积压很长的等待队列,如果操作比较频繁,而又不想处理因为等待造成的异常,就将这个值调大。
相关推荐
mongo-java-driver3.0以上jar压缩包大全 try { //1.连接池相关选项配置 MongoClientOptions options=MongoClientOptions.builder() .connectionsPerHost(poolSize) .minConnectionsPerHost(minpoolsize) ...
它还提供了丰富的选项来配置连接池,以优化资源利用率和性能。 在进行查询时,开发者可以使用BSON(Binary JSON)对象,或者直接使用Java类型的Document类,这使得数据操作更为直观: ```java BasicDBObject query...
1. **连接管理**:驱动程序提供了连接池,能够高效地管理和复用到MongoDB服务器的TCP连接,减少网络延迟,提高性能。 2. ** CRUD操作**:支持基本的创建(Create)、读取(Read)、更新(Update)和删除(Delete)...
同时,连接池的优化使得多线程环境下的并发访问更为高效。 其次,3.0版本加强了对异步操作的支持。Java驱动程序提供了异步API,允许开发者在不阻塞主线程的情况下执行数据库操作,这在处理大量并发请求时尤其有用。...
1. 连接管理:驱动提供了连接池,可以有效地管理和复用MongoDB服务器的连接,提高系统的并发能力。 2. 数据操作:支持CRUD(创建、读取、更新、删除)操作,通过`DB`、`DBCollection`等类实现对集合的访问,同时提供...
这个工具包通常会包括驱动程序本身和其他辅助开发的库,如连接池管理、监控工具等。 标签"mongodb"表明了这个压缩包的内容与MongoDB数据库紧密相关,意味着它是用于在Java环境中操作MongoDB数据库的。 在压缩包内...
驱动程序包含了多种功能,如连接池管理、自动重连、安全认证等,以确保可靠和高效的数据交互。 在描述中提到的“mongodb的java驱动”,确认了这个压缩包包含的是Java开发人员用于与MongoDB数据库通信的库。`mongo-...
在当前场景下,如果目标是连接到MongoDB服务器,那么使用`mongo-java-driver-3.2.2.jar`会更为合适,因为它提供了更好的功能和兼容性。 在实际项目中,将这些jar包添加到项目的类路径中是必要的,这样Java应用程序...
1. **连接池支持**:该版本引入了对连接池的支持,允许应用程序更有效地管理到MongoDB服务器的连接,提高了并发性能并减少了资源消耗。 2. **SSL/TLS支持**:安全套接层(SSL)和传输层安全(TLS)是用于加密网络通信的...
"mongo-java-driver-2.13.2.zip" 是一个包含MongoDB Java驱动程序的压缩包,版本号为2.13.2,主要用于Java环境中的MongoDB应用开发。 MongoDB Java驱动程序的核心功能包括: 1. 连接管理:驱动程序提供连接池,...
- 缓存管理:适当配置MongoClient实例的连接池大小和超时时间。 - 使用连接池:复用MongoClient实例以减少建立连接的开销。 - 查询优化:避免使用$match和$sort在早期阶段,尽可能减少数据传输量。 7. 异常处理...
17. **性能优化**:驱动程序提供了许多配置选项,如连接池大小、超时时间等,以优化应用程序性能。 `MongoDB Driver -JAVA 2.5.3 API.chm`文件包含了所有这些详细信息,包括方法签名、参数、返回值和示例代码,是...
例如,使用`MongoClientOptions`配置连接池大小,或者使用`MongoCredential`进行用户验证。此外,`MongoDB Java驱动程序`的版本更新也会带来新的特性与改进,比如`mongo-2.5.3.jar`是较旧的一个版本,可能不包含最新...
相反,我们需要使用专门的驱动程序,如`mongo-java-driver`,这个驱动程序包含了连接池管理的功能。在给定的`mongo-2.8.0.jar`文件中,很可能包含了MongoDB Java驱动程序的早期版本,该版本提供了连接池的支持。 ...
4. **连接池**:为了提高性能和资源管理,驱动程序通常会实现连接池,复用与MongoDB服务器的连接,而不是每次请求都创建新的连接。 5. **认证和安全性**:支持MongoDB的各种安全特性,包括SSL/TLS加密连接、身份...
在实际开发中,你可能还需要处理异常、配置连接池、使用分片集群、进行安全认证等高级特性。确保理解并正确使用MongoDB Java驱动程序的API,以及保持驱动程序版本与MongoDB服务器的兼容性,是成功集成MongoDB的关键...
其次,`mongodb-driver-core-3.9.0.jar`是驱动的核心部分,包含基础的网络通信和连接池管理功能。这个库处理与MongoDB服务器的低级别通信,如建立和管理TCP连接,执行命令,以及处理响应。MongoDB驱动的核心库还负责...
在标签中,“MongoDB”是数据库的名字,“Mongo连接池”指的是针对MongoDB数据库的连接池,“连接池”是数据库连接管理的一个通用概念,适用于各种数据库系统。 在压缩包“mongodb_pool”中,可能包含了以下内容: ...
驱动文件通常为`mysql-connector-java.jar`,支持连接池配置、SSL连接等特性。 3. **H2 Database JDBC Driver (H2)**:H2是一个轻量级、高性能的开源嵌入式和服务器模式的SQL数据库,适用于测试和开发。其JDBC驱动...
要使用MongoDB Java Driver连接MongoDB,首先需要在项目的`pom.xml`文件中添加依赖。以下是一个示例依赖: ```xml <groupId>org.mongodb <artifactId>mongodb-driver-sync <version>4.3.0 ``` 接下来,...