我有一个Web服务,每次从UI按下按钮时,它都会连接到弹性搜索并触发查询。这是每次执行的代码。问题是,经过一段时间,间歇性地,UI挂起。
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.
答案 0 :(得分:1)
这不太可能是一个真正的问题,更多的是Elasticsearch没有使用Tomcat管理的线程池的问题。因此,每当您在运行查询后重新启动Tomcat时,很可能认为它会发现内存泄漏。这对于#34;非托管&#34;是常见的。在Tomcat中触发的线程。话虽如此,您可以通过运行探查器,然后监视线程和资源来验证自身是否清理。如果没有正确清理,那么我建议在Elasticsearch的GitHub存储库中创建一个问题。
关于您在创建客户端时所做的事情:我绝对建议您不创建,使用,然后扔掉客户端。在启动时分配它,然后重用客户端,而不是根据需要不断重新创建它。然后在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);
}