首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MongoDB Java 多執行緒更新報錯:連線池耗盡解決方案

     編輯:程式設計綜合問答

錯誤現象

在使用 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。當所有連線被佔用且等待隊列滿時,新請求即拋出此異常。

解決方案

1. 降低併發執行緒數(快速修復)

將 number 設為合理值(如 10~20),避免超過連線池承載能力:

loadRunner = new LocationPressureTest(20, new Todo() { ... });

2. 調整連線池配置(根治)

根據業務併發需求,在建立 MongoClient 時配置連線池:

MongoClientOptions options = MongoClientOptions.builder()
    .connectionsPerHost(200)        // 連線池大小
    .maxWaitQueueSize(500)          // 等待隊列大小
    .connectTimeout(10000)
    .socketTimeout(30000)
    .build();

MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017), options);

3. 使用批量寫入優化效能

將多次 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));

4. 正確管理資源生命週期

  • 使用 try-with-resources 或 finally 確保 MongoClient 關閉。
  • 避免在循環中頻繁建立/銷毀連線。

最佳實踐總結

場景建議併發數連線池配置
低併發測試10-20預設即可
生產環境中等負載50-100connectionsPerHost=200, maxWaitQueueSize=500
高併發寫入配合批量寫入connectionsPerHost=300+, 使用 bulkWrite

核心原則:併發執行緒數 ≤ 連線池大小 + 等待隊列,並善用批量操作提升吞吐量。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved