【问题标题】:ConnectionPoolTimeoutException when reaching the max pool size while inserting documents插入文档时达到最大池大小时发生 ConnectionPoolTimeoutException
【发布时间】:2015-04-30 08:52:47
【问题描述】:

我已经玩了几天 Azure DocumentDB,在插入我的数据时遇到了一个奇怪的行为。 (我用的是maven https://github.com/Azure/azure-documentdb-java的java sdk 1.0版)

要插入数据,我会遍历我的 pojo 并尝试像这样插入它们:

for (Order order : jsonImporter.getOrderList()) {
    Document doc = new Document(gson.toJson(order, Order.class));
    doc.setId(order.uuid);
    doc.set(TYPE, TYPE_ORDER);
    try {
        client.createDocument(getCollection().getSelfLink(), doc, null, true);
    } catch (DocumentClientException e) {
        System.err.printf("AzureDocumentDB - insertOrder request failed (order uuid %s)", order.uuid);
        System.err.println(e.getMessage());
    }
}

问题是,当我到达第 100 个元素(即最大连接池大小)时,我得到一个异常,即我的连接池无法为我提供另一个连接。 我也尝试修改连接池的设置,增加连接数据,减少“IdleConnectionTimeout”,提前释放连接,但没有成功。
例如,当我将池大小增加到 500 时,在第 500 个元素之后出现异常。

ConnectionPolicy connectionPolicy = new ConnectionPolicy();
connectionPolicy.setMaxPoolSize(500);
connectionPolicy.setIdleConnectionTimeout(10);
client = new DocumentClient(END_POINT, MASTER_KEY, connectionPolicy, ConsistencyLevel.Session);

有人在我的代码中看到 API 滥用吗?有人在插入数据时遇到过同样的行为吗?或者 sdk 或 apache http 客户端中是否存在导致连接未释放的已知错误?我将不胜感激。

例外:

java.lang.IllegalStateException: Http client execution failed.
    at com.microsoft.azure.documentdb.GatewayProxy.performPostRequest(GatewayProxy.java:350)
    at com.microsoft.azure.documentdb.GatewayProxy.doCreate(GatewayProxy.java:90)
    at com.microsoft.azure.documentdb.DocumentClient.doCreate(DocumentClient.java:1968)
    at com.microsoft.azure.documentdb.DocumentClient.createDocument(DocumentClient.java:456)
    ...
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
    at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:226)
    at org.apache.http.impl.conn.PoolingClientConnectionManager$1.getConnection(PoolingClientConnectionManager.java:195)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
    at com.microsoft.azure.documentdb.GatewayProxy.performPostRequest(GatewayProxy.java:347)

【问题讨论】:

    标签: java apache-httpclient-4.x azure-cosmosdb


    【解决方案1】:

    您看到 ConnectionPoolTimeoutException 是因为 DocumentClient 在调用 createXXXXXXXX() 时不会自动关闭流。此行为旨在支持 createAttachment() 的流式 blob 附件。

    要关闭流,可以调用close()关闭流或调用.getResource()返回资源然后关闭流。

    换句话说,替换以下行:

    client.createDocument(getCollection().getSelfLink(), doc, null, true);

    与:

    client.createDocument(getCollection().getSelfLink(), doc, null, true).close();

    或者:

    doc = client.createDocument(getCollection().getSelfLink(), doc, null, true).getResource();

    【讨论】:

    • 谢谢,下次我会更深入地研究 API。我看到你在github的例子中总是使用getResource(),但我认为它只是为了获取插入的文档。也许只需在 cmets 中添加几句话,这也负责关闭连接。
    • 如果在运行代码时出现错误会发生什么情况 doc = client.createDocument(getCollection().getSelfLink(), doc, null, true).getResource(); ?如何强制关闭与 catch 块的连接?似乎它导致我一些“超时等待来自池的连接”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 2016-12-23
    • 2014-07-03
    • 1970-01-01
    • 2021-03-05
    • 2020-01-02
    相关资源
    最近更新 更多