Java开发MongoDB应用:是否应仅创建一次MongoClient实例?
MongoDB Java驱动:别再每次查询都创建MongoClient了!
嘿,我之前刚好用Java开发MongoDB应用的时候也犯过一模一样的错!最开始也是照着JDBC的老思路,每次查数据都new一个MongoClient,用完就close,结果后来压测的时候性能差得离谱,查了官方文档才发现自己完全误解了MongoClient的作用。
先搞懂MongoClient的本质
MongoDB官方文档里明确说了:MongoClient实例本身就是一个连接池的实现,而不是单个数据库连接。
当你创建一个MongoClient的时候,驱动已经在后台帮你维护了一组和MongoDB服务器的持久TCP连接。每次执行查询、插入这些操作时,驱动会从连接池里取出一个可用的连接来用,操作完成后再把连接放回池里,不需要重新建立连接——而建立TCP连接的开销(三次握手、认证这些)其实非常大,频繁创建/关闭MongoClient就等于反复销毁和重建整个连接池,性能能好才怪!
正确的做法:复用单个MongoClient实例
整个应用的生命周期里,你只需要一个MongoClient实例就够了,所有数据库操作都复用它。这里给你一个简单的单例实现示例:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.MongoClientSettings; public class MongoSingleton { // 静态单例实例,类加载时初始化 private static final MongoClient MONGO_CLIENT; static { // 可以根据需要配置连接参数,比如连接字符串、连接池大小等 MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(new com.mongodb.ConnectionString("mongodb://localhost:27017")) .build(); MONGO_CLIENT = MongoClients.create(settings); } // 对外提供获取实例的方法 public static MongoClient getInstance() { return MONGO_CLIENT; } // 只有当整个应用关闭时才需要调用这个方法,销毁连接池 public static void shutdown() { if (MONGO_CLIENT != null) { MONGO_CLIENT.close(); } } }
日常使用示例
之后你每次操作数据库的时候,直接拿这个单例实例就行,完全不用每次创建和关闭:
// 获取单例MongoClient MongoClient client = MongoSingleton.getInstance(); // 获取数据库和集合 MongoDatabase db = client.getDatabase("my_app_db"); MongoCollection<Document> userCollection = db.getCollection("users"); // 执行查询操作 Document user = userCollection.find(eq("user_id", 123)).first(); // 这里不需要close client!连接会自动放回连接池
额外注意事项
- 别在每次请求/查询里创建MongoClient:这会导致大量无效的TCP连接,拖垮应用性能和MongoDB服务器
- 应用关闭时记得关闭MongoClient:比如在Web应用的
ServletContextListener的contextDestroyed方法里调用MongoSingleton.shutdown(),或者在Spring Boot应用里用@PreDestroy注解的方法来执行关闭 - 可以自定义连接池参数:比如通过
MongoClientSettings设置最大连接数、连接超时、空闲超时等,适配你的应用并发需求
内容的提问来源于stack exchange,提问作者Adey
相关产品推荐
相关产品推荐

