我有一个Java Web应用程序,它使用Solrj API索引Solr 4.4中的数据,并且还使用其HTTP API直接查询Solr。我的webapp和Solr都在同一台服务器上运行自己的Tomcat实例。我刚刚使用默认的HttpClient
配置更改了我的应用程序的HttpSolrServer,以使用PoolingClientConnectionManager使用SystemDefaultHttpClient的自定义配置单例实例(Spring bean)。
我的问题是我的Solr webapp每隔几天就会抛出OutOfMemoryExceptions。我可以看到netstat
和lsof
我的应用程序在向Solr发出请求之后将套接字保持为处于CLOSE_WAIT状态的Solr,这可能表明我没有正确释放空闲连接。但是,Solr进程似乎没有保持任何套接字从其末端打开。
我对这篇文章的目标是确认或消除我滥用HttpClient API可能导致Solr内存问题的理论。我认为它可能(并且会)导致我的应用程序出现问题,但不会导致我连接的服务器。
Solr在我申请大量使用一段时间后,一夜之间就抛出了这些例外,而不是在大量使用期间。如果它不是以某种方式与延迟连接有关,我不太确定下一步要去哪里。运行的Tomcat实例已经分配了3.5 GB的最大堆空间(-Xmx),所以我怀疑它只需要更多。任何帮助缩小我的努力都会很有帮助。
我的HttpClient实例看起来像这样:
SystemDefaultHttpClient httpClient = new SystemDefaultHttpClient();
httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "password"));
PoolingClientConnectionManager cm =
(PoolingClientConnectionManager) httpClient.getConnectionManager();
cm.setMaxTotal(200);
HttpHost localhost = new HttpHost("localhost", 8100);
cm.setMaxPerRoute(new HttpRoute(localhost), 200);
我的SolrServer实例看起来像这样:
SolrServer ss = new HttpSolrServer("http://localhost:8100/solr/core1", httpClient);
我的Solr HTTP请求看起来像这样:
HttpPost httpPost = new HttpPost("http://localhost:8100/solr/core1/select");
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("q", "query terms"));
nvps.add(new BasicNameValuePair("fl", "field1,field2,field3"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse response = httpClient.execute(httpPost);
InputStream inputStream=null;
try {
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
//do something with the response body
} finally {
inputStream.close();
}
答案 0 :(得分:0)
没有出现在你的特定场景中,但是我也非常相似你是否也接受了非法状态。
请你能提供一些查询,没有文件,tomcat中的线程数 和tomcat中的垃圾收集参数
你也可以尝试增加线程数来解决这个问题
问候
拉杰特
答案 1 :(得分:0)
Solr中的OutOfMemoryErrors不是由我在应用程序中可能或可能没有的任何连接管理缺陷引起的。除了在不适当的测试服务器上的高于平均使用率之外,似乎我的问题在Solr中关于合并段和/或垃圾收集的某处。