异常信息如下:
SEVERE: null:java.lang.IllegalArgumentException: port out of range:-1
at java.net.InetSocketAddress.<init>(InetSocketAddress.java:83)
at java.net.InetSocketAddress.<init>(InetSocketAddress.java:63)
at
org.apache.solr.cloud.SolrZkServerProps.setClientPort(SolrZkServer.java:315)
at
org.apache.solr.cloud.SolrZkServerProps.getMySeverId(SolrZkServer.java:278)
at
org.apache.solr.cloud.SolrZkServerProps.parseProperties(SolrZkServer.java:453)
at
org.apache.solr.cloud.SolrZkServer.parseConfig(SolrZkServer.java:90)
at
org.apache.solr.core.CoreContainer.initZooKeeper(CoreContainer.java:208)
按照solr官网邮件中的解决方式是无法实现的,错误配置如下:
-DzkRun -DzkHost=nodeA:9983,nodeB:9983,nodeC:9983,nodeD:9983/solrroot -DnumShards=2 -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=MyConfig
错误根本原因不是所谓独立zookeeper集群造成,而是因为带有-DzkRun参数造成,该参数是用来启动内部嵌入zookeeper的,外部集群不需要加入该参数。
通过源码可看出该问题出现原因:
1,注入zookeeper集群信息源码如下:
public static void injectServers(Properties props, String zkRun, String zkHost) {
// if clientPort not already set, use zkRun
if (zkRun != null && props.getProperty("clientPort")==null) {
int portIdx = zkRun.lastIndexOf(':');
if (portIdx > 0) {
String portStr = zkRun.substring(portIdx+1);
props.setProperty("clientPort", portStr);
}
}
boolean hasServers = hasServers(props);
if (!hasServers && zkHost != null) {
int alg = Integer.parseInt(props.getProperty("electionAlg","3").trim());
String[] hosts = zkHost.split(",");
int serverNum = 0;
for (String hostAndPort : hosts) {
hostAndPort = hostAndPort.trim();
int portIdx = hostAndPort.lastIndexOf(':');
String clientPortStr = hostAndPort.substring(portIdx+1);
int clientPort = Integer.parseInt(clientPortStr);
String host = hostAndPort.substring(0,portIdx);
String serverStr = host + ':' + (clientPort+1);
// zk leader election algorithms other than 0 need an extra port for leader election.
if (alg != 0) {
serverStr = serverStr + ':' + (clientPort+2);
}
props.setProperty("server."+serverNum, serverStr);
serverNum++;
}
}
}