tomcat - Elasticsearch 中 Threadlocals 的内存泄漏相关问题

标签 tomcat elasticsearch

我有一个 Web 服务,每次从 UI 按下按钮时,它都会连接到 Elasticsearch 并触发查询。这是每次都执行的代码。问题是,一段时间后,用户界面间歇性地挂起。

private static final String CONFIG_CLUSTER_NAME = "cluster.name";

private static final String CLUSTER_NAME = "sample_es";
private static final String[] transportAddress = {
    //Machine details
};

private static final int transportPort = 9300;

public static Client initClient(){
    settings = ImmutableSettings.settingsBuilder().put(CONFIG_CLUSTER_NAME, CLUSTER_NAME).build();

        Client client = new TransportClient(settings);
        for (int i=0 ; i < transportAddress.length-1 ; i++){
            ((TransportClient)client).addTransportAddress(new InetSocketTransportAddress(transportAddress[i], transportPort));
        }
        logger.info("TransportClient Created"); 
        return client;  
}


public static int query( String query) throws Exception
{
    Client client = null;
    try{

            client = initClient();

            //Query search code

    }catch(Exception e){
            e.printStackTrace();
    }finally{
        if(client != null){
            client.close();
            logger.info("TransportClient Closed");
        }
    }
        return result_count;
}

每当我们重新启动 tomcat 服务器时,这就是我们在日志中看到的错误消息。我们应该如何解决这个问题?

[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom$1] (value
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom$1@5838ce3e]) and a value of type
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom] (value 
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom@796c75b1]) but failed to remove it
when the web application was stopped. This is very likely to create a memory leak.

最佳答案

这不太可能是一个真正的问题,更多的是 Elasticsearch 没有使用由 Tomcat 管理的线程池。因此,每当您在接近运行查询后重新启动 Tomcat 时,它很可能认为它发现了内存泄漏。这对于在 Tomcat 中触发的“非托管”线程很常见。话虽如此,您可以通过运行探查器然后监控线程和资源来验证是否正在自行清理。如果没有正确清理,那么我建议在 Elasticsearch 的 GitHub 存储库上创建一个问题。

关于您在客户端创建方面所做的工作:我绝对建议您不要创建、使用然后丢弃客户端。在开始时分配它,然后重用客户端而不是不断地按需重新创建它。然后添加一个shutdown钩子(Hook),在Tomcat要停止的时候关闭它。另外,for (int i=0 ; i < transportAddress.length-1 ; i++)正在跳过最后一个传输地址;使用 i < transportAddress.length没有 -1 .

不相关,但都是 Elasticsearch Client实现 AutoCloseable (在 Java 7 中添加),这意味着您可以简化代码以自动关闭它如果您想继续这样做:

try (Client client = initClient()) {
    // Query search code
}
catch (Exception e) {
    logger.warning("An unexpected error occurred for the query: {}",
                   query, e);
}

关于tomcat - Elasticsearch 中 Threadlocals 的内存泄漏相关问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27090676/

相关文章:

生产环境的 Tomcat MaxThreads 数量

java - HTTP 状态 404 -/elecMaven/system/actingIndex.jsp,但我的配置是正确的

java - Tomcat 服务器工作,但无法部署我的 JSP 文件

java - 弹性搜寻和Y10k(超过4位数字的年份)

elasticsearch - ElasticSearch多字段不起作用

elasticsearch - 在 Kibana 中通配符搜索消息字段中的字符串文本

Java:Spring boot Tomcat 访问日志未在 Tomcat 启动时创建

java - 使用 Equinox Servle Bridge 将 OSGi 应用程序部署到 Tomcat 时如何配置 Log4J?

elasticsearch - elasticsearch减去两个数据集之间的数值字段

angularjs - 如何使用 ElasticSearch 获取结果页面?