mongoDB 常见三种异常解析 (附配置)

本文介绍了MongoDB的配置参数及常见异常处理方法,包括MongoWaitQueueFullException、MongoTimeoutException和MongoInterruptedException等异常的产生原因及解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配置

mongoDB配置

<mongo:mongo-client id="mongoClient" host="${mongo.host}" port="${mongo.port}" credentials="${mongo.user}:${mongo.pwd}@${mongo.defaultDbName}">
        <mongo:client-options
            connections-per-host="${mongo.connectionsPerHost}"
            min-connections-per-host="${mongo.minConnectionsPerHost}"
            threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
            connect-timeout="${mongo.connectTimeout}"
            max-wait-time="${mongo.maxWaitTime}"
            socket-keep-alive="${mongo.socketKeepAlive}"
            socket-timeout="${mongo.socketTimeout}"
            description="${mongo.description}"
            max-connection-idle-time="${mongo.maxConnectionIdleTime}"
            max-connection-life-time="${mongo.maxConnectionLifeTime}"
            heartbeat-socket-timeout="${mongo.heartbeatSocketTimeout}"
            heartbeat-connect-timeout="${mongo.heartbeatConnectTimeout}"
            min-heartbeat-frequency="${mongo.minHeartbeatFrequency}"
            heartbeat-frequency="${mongo.heartbeatFrequency}" />
    </mongo:mongo-client>
mongo.host=127.0.0.1
mongo.port=27017
mongo.defaultDbName=data
mongo.user=test
mongo.pwd=123456

# 最大连接数,每一台服务器
mongo.connectionsPerHost=1
# 可阻塞线程队列容量
mongo.threadsAllowedToBlockForConnectionMultiplier=5
# 每一台服务器的最小连接数
mongo.minConnectionsPerHost=1

#连接超时时间 1分钟
mongo.connectTimeout=60000
#等待时间 120000 2 * 60 * 1000
mongo.maxWaitTime=120000
#Socket超时时间
mongo.socketTimeout=0
#保持连接
mongo.socketKeepAlive=true

mongo.description=mongodb

## 连接空闲时间8小时,否则连接太过频繁
mongo.maxConnectionIdleTime=28800000
mongo.maxConnectionLifeTime=0

#mongo 心跳
mongo.heartbeatSocketTimeout=10000
mongo.heartbeatConnectTimeout=15000
mongo.minHeartbeatFrequency=5000
mongo.heartbeatFrequency=100000

异常1 MongoWaitQueueFullException

请求线程过多时,阻塞的线程放入不到队列之中,

线程数量 - connectionsPerHost >  threadsAllowedToBlockForConnectionMultiplier * connectionsPerHost


线程数量 = connectionsPerHost * (threadsAllowedToBlockForConnectionMultiplier + 1)

根据以上公式可以得出
增大threadsAllowedToBlockForConnectionMultiplier 或者 connectionsPerHost 即可

通过多线程模拟即可

com.mongodb.MongoWaitQueueFullException: Too many threads are already waiting for a connection. Max number of threads (maxWaitQueueSize) of 5 has been exceeded.
    at com.mongodb.connection.DefaultConnectionPool.createWaitQueueFullException(DefaultConnectionPool.java:274)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:93)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:86)
    at com.mongodb.connection.DefaultServer.getConnection(DefaultServer.java:77)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:86)
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:422)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415)
    at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:133)
    at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:60)
    at com.mongodb.Mongo.execute(Mongo.java:819)
    at com.mongodb.Mongo$2.execute(Mongo.java:802)
    at com.mongodb.DBCollection.executeWriteOperation(DBCollection.java:340)
    at com.mongodb.DBCollection.insert(DBCollection.java:335)
    at com.mongodb.DBCollection.insert(DBCollection.java:326)
    at com.mongodb.DBCollection.insert(DBCollection.java:296)
    at com.mongodb.DBCollection.insert(DBCollection.java:262)
    at com.mongodb.DBCollection.insert(DBCollection.java:199)
    at org.springframework.data.mongodb.core.MongoTemplate$9.doInCollection(MongoTemplate.java:1054)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:482)
    ... 22 more

异常2 MongoTimeoutException

阻塞队列的线程等待连接超时

解决方案:: 增大maxWaitTime参数

复现方案: 通过多线程、大数据量,无索引查询。调小maxWaitTime测试即可

Caused by: com.mongodb.MongoTimeoutException: Timeout waiting for a pooled item after 5000 MILLISECONDS
    at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:127)
    at com.mongodb.connection.DefaultConnectionPool.getPooledConnection(DefaultConnectionPool.java:256)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:97)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:86)
    at com.mongodb.connection.DefaultServer.getConnection(DefaultServer.java:77)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:86)
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:431)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:406)
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:709)
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:81)
    at com.mongodb.Mongo.execute(Mongo.java:810)
    at com.mongodb.Mongo$2.execute(Mongo.java:797)
    at com.mongodb.DBCursor.initializeCursor(DBCursor.java:871)
    at com.mongodb.DBCursor.hasNext(DBCursor.java:142)
    at com.mongodb.DBCursor.one(DBCursor.java:680)
    at com.mongodb.DBCollection.findOne(DBCollection.java:831)
    at com.mongodb.DBCollection.findOne(DBCollection.java:794)
    at com.mongodb.DBCollection.findOne(DBCollection.java:741)
    at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2197)
    at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2181)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:1925)
    ... 18 more

异常3 MongoInterruptedException

由于线程被中断导致mongo查询被中断

查询中断异常

Caused by: com.mongodb.MongoInterruptedException: Interrupted acquiring a permit to retrieve an item from the pool 
    at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:186)
    at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:126)
    at com.mongodb.connection.DefaultConnectionPool.getPooledConnection(DefaultConnectionPool.java:256)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:97)
    at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:86)
    at com.mongodb.connection.DefaultServer.getConnection(DefaultServer.java:77)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:86)
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:422)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:397)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:232)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:55)
    at com.mongodb.Mongo.execute(Mongo.java:810)
    at com.mongodb.Mongo$2.execute(Mongo.java:797)
    at com.mongodb.DBCollection.getCount(DBCollection.java:1004)
    at com.mongodb.DBCollection.count(DBCollection.java:854)
    at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:779)
    at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:777)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:482)
    ... 33 common frames omitted
Caused by: java.lang.InterruptedException: null
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1326)
    at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:409)
    at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:180)
    ... 50 common frames omitted

复现程序

    final Thread t1 = new Thread(() -> {
            userRepository.findOneByName(UUID.randomUUID().toString());
            userRepository.findOneByName(UUID.randomUUID().toString());
            userRepository.findOneByName(UUID.randomUUID().toString());
            userRepository.findOneByName(UUID.randomUUID().toString());
            userRepository.findOneByName(UUID.randomUUID().toString());
            userRepository.findOneByName(UUID.randomUUID().toString());
        });

        t1.start();

        Thread.sleep(10000);

        t1.interrupt();

        while (true) {

        }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值