我目前正在使用SolrJ
用LBHttpSolrServer
开发Solr客户端,因为我有几个Solr节点。
问题是我有一个具有200多个Solr内核的应用程序。
因此,我为每个Solr核心创建了一个LBHttpSolrServer
实例(如文档所示):
LBHttpSolrServer solrServer = new LBHttpSolrServer(
"http://host1:8080/solr/mySolrCore",
"http://host2:8080/solr/mySolrCore"
);
但是,它在我的应用程序中产生了200多个
LBHttpSolrServer
实例。如docs所示,如果一个节点出现故障,SolrJ将为
LBHttpSolrServer
的每个实例创建一个线程,因此将增加200个以上的线程,并使我的应用程序饱和。有没有一种方法可以创建仅
LBHttpSolrServer
的一个实例,该实例将由我的所有内核共享? 最佳答案
是的,不幸的是,这是如何实现LBHttpSolrServer的:
/** The provided httpClient should use a multi-threaded connection manager */
public LBHttpSolrServer(HttpClient httpClient, ResponseParser parser, String...solrServerUrl) {
clientIsInternal = (httpClient == null);
this.parser = parser;
if (httpClient == null) {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(HttpClientUtil.PROP_USE_RETRY, false);
this.httpClient = HttpClientUtil.createClient(params);
} else {
this.httpClient = httpClient;
}
for (String s: solrServerUrl) {
ServerWrapper wrapper = new ServerWrapper(makeServer(s));
aliveServers.put(wrapper.getKey(), wrapper);
}
updateAliveList();
}
要解决此问题,您可以使用LBHttpSolrServer提供的不同请求方法:
public Rsp request(Req req)
而不是从SolrServer覆盖的默认值
public NamedList<Object> request(final SolrRequest request)
LBHttpSolrServer提供的request(Req req)方法允许通过Req参数指定Solr URL的列表
"@param req contains both the request as well as the list of servers to query"
在这种情况下,LBHttpSolrServer将仅继续实例化HttpSolrServers,直到一个可行:
for (String serverStr : req.getServers()) {
serverStr = normalize(serverStr);
// if the server is currently a zombie, just skip to the next one
ServerWrapper wrapper = zombieServers.get(serverStr);
if (wrapper != null) {
// System.out.println("ZOMBIE SERVER QUERIED: " + serverStr);
if (skipped.size() < req.getNumDeadServersToTry())
skipped.add(wrapper);
continue;
}
rsp.server = serverStr;
HttpSolrServer server = makeServer(serverStr);
ex = doRequest(server, req, rsp, isUpdate, false, null);
if (ex == null) {
return rsp; // SUCCESS
}