在使用 MongoDB Java Driver 進行高併發更新操作時,拋出 MongoWaitQueueFullException: Too many threads are already waiting for a connection. Max number of threads (maxWaitQueueSize) of 50 has been exceeded.
程式碼中建立了 347 個執行緒(number = 347),每個執行緒無限循環執行 col.update(...)。MongoDB Java Driver 預設連線池大小為 100,等待隊列大小為 50。當所有連線被佔用且等待隊列滿時,新請求即拋出此異常。
將 number 設為合理值(如 10~20),避免超過連線池承載能力:
loadRunner = new LocationPressureTest(20, new Todo() { ... });
根據業務併發需求,在建立 MongoClient 時配置連線池:
MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(200) // 連線池大小
.maxWaitQueueSize(500) // 等待隊列大小
.connectTimeout(10000)
.socketTimeout(30000)
.build();
MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017), options);
將多次 update 合併為 bulkWrite,減少網路往返:
List> writes = new ArrayList<>();
for (int i = 0; i < batchSize; i++) {
writes.add(new UpdateOneModel<>(
Filters.eq("_id", randomId),
Updates.set("coordinates", new double[]{lon, lat})
));
}
collection.bulkWrite(writes, new BulkWriteOptions().ordered(false));
try-with-resources 或 finally 確保 MongoClient 關閉。| 場景 | 建議併發數 | 連線池配置 |
|---|---|---|
| 低併發測試 | 10-20 | 預設即可 |
| 生產環境中等負載 | 50-100 | connectionsPerHost=200, maxWaitQueueSize=500 |
| 高併發寫入 | 配合批量寫入 | connectionsPerHost=300+, 使用 bulkWrite |
核心原則:併發執行緒數 ≤ 連線池大小 + 等待隊列,並善用批量操作提升吞吐量。