等待来自池的连接超时 - 尽管有单个 SolrServer
Timeout waiting for connection from pool - despite single SolrServer
我们的 solrServer 客户端的连接池 运行 立即出现连接问题,即使使用数百个连接池(我们已经尝试了 1024 个,只是为了更好的衡量标准)。
据我了解,以下异常可能是由于未使用单例 HttpSolrServer 对象引起的。但是,请参阅下面的 XML 配置:
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:232)
at org.apache.http.impl.conn.PoolingClientConnectionManager.getConnection(PoolingClientConnectionManager.java:199)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:455)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at org.apache.solr.client.solrj.impl.HttpSolrServer.executeMethod(HttpSolrServer.java:448)
XML 配置:
<solr:solr-server id="solrServer" url="http://solr.url.domain/"/>
<solr:repositories base-package="de.ourpackage.data.solr" multicore-support="true"/>
至此,我们不知所措。我们是 运行 tomcat7 上的 Web 应用程序。每当用户请求一个新网站时,我们都会向 Solr 服务器发送一个或多个请求,请求我们需要的任何内容,通常是单个条目或 20 页(使用 Spring 数据)。
至于我们实施的其余部分,我们使用抽象的 SolrOperationsrepository class,它由我们的每个存储库(每个核心一个存储库)扩展。
下面是我们如何设置我们的solrServer。我怀疑我们在这里做了一些根本性的错误,这就是我们的连接溢出的原因。 根据日志,它们总是被返回到池中,顺便说一句。
private SolrOperations solrOperations;
@SuppressWarnings("unchecked")
public final Class<T> getEntityClass() {
return (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public final SolrOperations getSolrOperations() {
/*HttpSolrServer solrServer = (HttpSolrServer)solrOperations.getSolrServer();
solrServer.getHttpClient().getConnectionManager().closeIdleConnections(500, TimeUnit.MILLISECONDS);*/
logger.info("solrOperations: " + solrOperations);
return solrOperations;
}
@Autowired
public final void setSolrServer(SolrServer solrServer) {
try {
String core = SolrServerUtils.resolveSolrCoreName(getEntityClass());
SolrTemplate template = templateHolder.get(core);
/*solrServer.setConnectionTimeout(500);
solrServer.setMaxTotalConnections(2048);
solrServer.setDefaultMaxConnectionsPerHost(2048);
solrServer.getHttpClient().getConnectionManager().closeIdleConnections(500, TimeUnit.MILLISECONDS);*/
if ( template == null ) {
template = new SolrTemplate(new MulticoreSolrServerFactory(solrServer));
template.setSolrCore(core);
template.afterPropertiesSet();
logger.debug("Creating new SolrTemplate for core '" + core + "'");
templateHolder.put(core, template);
}
logger.debug("setting SolrServer " + template);
this.solrOperations = template;
} catch (Exception e) {
logger.error("cannot set solrServer...", e);
}
}
注释掉的代码主要用于测试目的。我还在其他地方读到,您不能即时操作 solrServer 对象。这就引出了一个问题,我如何在 XML 配置中设置 timeout/poolsize?
存储库的实现如下所示:
@Repository(value="stellenanzeigenSolrRepository")
public class StellenanzeigenSolrRepositoryImpl extends SolrOperationsRepository<Stellenanzeige> implements StellenanzeigenSolrRepositoryCustom {
...
public Query createQuery(Criteria criteria, Sort sort, Pageable pageable) {
Query resultQuery = new SimpleQuery(criteria);
if ( pageable != null ) resultQuery.setPageRequest(pageable);
if ( sort != null ) resultQuery.addSort(sort);
return resultQuery;
}
public Page<Stellenanzeige> findBySearchtext(String searchtext, Pageable pageable) {
Criteria searchtextCriteria = createSearchtextCriteria(searchtext);
Query query = createQuery(searchtextCriteria, null, pageable);
return getSolrOperations().queryForPage(query, getEntityClass());
}
...
}
你们中的任何人都可以指出我们所犯的可能导致此问题的错误吗?就像我说的,我们不知所措。提前致谢,当然,我会在取得进展或您要求更多信息时更新问题。
MulticoreServerFactory 总是returns HttpClient 的对象,它只允许对同一主机的 2 个并发连接,从而导致上述问题。
这似乎是 spring-data-solr 的一个错误,可以通过创建自定义工厂并覆盖一些方法来解决。
编辑:MultiCoreSolrServerFactory 中的克隆方法已损坏。这还没有得到纠正。由于我的一些同事最近 运行 遇到了这个问题,我将在此 post 解决方法 - 创建您自己的 class 并覆盖一个方法。
public class CustomMulticoreSolrServerFactory extends MulticoreSolrServerFactory {
public CustomMulticoreSolrServerFactory(final SolrServer solrServer) {
super(solrServer);
}
@Override
protected SolrServer createServerForCore(final SolrServer reference, final String core) {
// There is a bug in the original SolrServerUtils.cloneHttpSolrServer()
// method
// that doesn't clone the ConnectionManager and always returns the
// default
// PoolingClientConnectionManager with a maximum of 2 connections per
// host
if (StringUtils.hasText(core) && reference instanceof HttpSolrServer) {
HttpClient client = ((HttpSolrServer) reference).getHttpClient();
String baseURL = ((HttpSolrServer) reference).getBaseURL();
baseURL = SolrServerUtils.appendCoreToBaseUrl(baseURL, core);
return new HttpSolrServer(baseURL, client);
}
return reference;
}
}
我们的 solrServer 客户端的连接池 运行 立即出现连接问题,即使使用数百个连接池(我们已经尝试了 1024 个,只是为了更好的衡量标准)。
据我了解,以下异常可能是由于未使用单例 HttpSolrServer 对象引起的。但是,请参阅下面的 XML 配置:
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:232)
at org.apache.http.impl.conn.PoolingClientConnectionManager.getConnection(PoolingClientConnectionManager.java:199)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:455)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at org.apache.solr.client.solrj.impl.HttpSolrServer.executeMethod(HttpSolrServer.java:448)
XML 配置:
<solr:solr-server id="solrServer" url="http://solr.url.domain/"/>
<solr:repositories base-package="de.ourpackage.data.solr" multicore-support="true"/>
至此,我们不知所措。我们是 运行 tomcat7 上的 Web 应用程序。每当用户请求一个新网站时,我们都会向 Solr 服务器发送一个或多个请求,请求我们需要的任何内容,通常是单个条目或 20 页(使用 Spring 数据)。
至于我们实施的其余部分,我们使用抽象的 SolrOperationsrepository class,它由我们的每个存储库(每个核心一个存储库)扩展。
下面是我们如何设置我们的solrServer。我怀疑我们在这里做了一些根本性的错误,这就是我们的连接溢出的原因。 根据日志,它们总是被返回到池中,顺便说一句。
private SolrOperations solrOperations;
@SuppressWarnings("unchecked")
public final Class<T> getEntityClass() {
return (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public final SolrOperations getSolrOperations() {
/*HttpSolrServer solrServer = (HttpSolrServer)solrOperations.getSolrServer();
solrServer.getHttpClient().getConnectionManager().closeIdleConnections(500, TimeUnit.MILLISECONDS);*/
logger.info("solrOperations: " + solrOperations);
return solrOperations;
}
@Autowired
public final void setSolrServer(SolrServer solrServer) {
try {
String core = SolrServerUtils.resolveSolrCoreName(getEntityClass());
SolrTemplate template = templateHolder.get(core);
/*solrServer.setConnectionTimeout(500);
solrServer.setMaxTotalConnections(2048);
solrServer.setDefaultMaxConnectionsPerHost(2048);
solrServer.getHttpClient().getConnectionManager().closeIdleConnections(500, TimeUnit.MILLISECONDS);*/
if ( template == null ) {
template = new SolrTemplate(new MulticoreSolrServerFactory(solrServer));
template.setSolrCore(core);
template.afterPropertiesSet();
logger.debug("Creating new SolrTemplate for core '" + core + "'");
templateHolder.put(core, template);
}
logger.debug("setting SolrServer " + template);
this.solrOperations = template;
} catch (Exception e) {
logger.error("cannot set solrServer...", e);
}
}
注释掉的代码主要用于测试目的。我还在其他地方读到,您不能即时操作 solrServer 对象。这就引出了一个问题,我如何在 XML 配置中设置 timeout/poolsize?
存储库的实现如下所示:
@Repository(value="stellenanzeigenSolrRepository")
public class StellenanzeigenSolrRepositoryImpl extends SolrOperationsRepository<Stellenanzeige> implements StellenanzeigenSolrRepositoryCustom {
...
public Query createQuery(Criteria criteria, Sort sort, Pageable pageable) {
Query resultQuery = new SimpleQuery(criteria);
if ( pageable != null ) resultQuery.setPageRequest(pageable);
if ( sort != null ) resultQuery.addSort(sort);
return resultQuery;
}
public Page<Stellenanzeige> findBySearchtext(String searchtext, Pageable pageable) {
Criteria searchtextCriteria = createSearchtextCriteria(searchtext);
Query query = createQuery(searchtextCriteria, null, pageable);
return getSolrOperations().queryForPage(query, getEntityClass());
}
...
}
你们中的任何人都可以指出我们所犯的可能导致此问题的错误吗?就像我说的,我们不知所措。提前致谢,当然,我会在取得进展或您要求更多信息时更新问题。
MulticoreServerFactory 总是returns HttpClient 的对象,它只允许对同一主机的 2 个并发连接,从而导致上述问题。
这似乎是 spring-data-solr 的一个错误,可以通过创建自定义工厂并覆盖一些方法来解决。
编辑:MultiCoreSolrServerFactory 中的克隆方法已损坏。这还没有得到纠正。由于我的一些同事最近 运行 遇到了这个问题,我将在此 post 解决方法 - 创建您自己的 class 并覆盖一个方法。
public class CustomMulticoreSolrServerFactory extends MulticoreSolrServerFactory {
public CustomMulticoreSolrServerFactory(final SolrServer solrServer) {
super(solrServer);
}
@Override
protected SolrServer createServerForCore(final SolrServer reference, final String core) {
// There is a bug in the original SolrServerUtils.cloneHttpSolrServer()
// method
// that doesn't clone the ConnectionManager and always returns the
// default
// PoolingClientConnectionManager with a maximum of 2 connections per
// host
if (StringUtils.hasText(core) && reference instanceof HttpSolrServer) {
HttpClient client = ((HttpSolrServer) reference).getHttpClient();
String baseURL = ((HttpSolrServer) reference).getBaseURL();
baseURL = SolrServerUtils.appendCoreToBaseUrl(baseURL, core);
return new HttpSolrServer(baseURL, client);
}
return reference;
}
}