通过TransportClient这个接口,我们可以不启动节点就可以和es集群进行通信,它需要指定es集群中其中一台或多台机的ip地址和端口,例子如下:
Client client = new TransportClient()
.addTransportAddress(newInetSocketTransportAddress("host1", 9300))
.addTransportAddress(newInetSocketTransportAddress("host2", 9300));
client.close();
如果你需要更改集群名(默认是elasticsearch),需要如下设置:
Settings settings =ImmutableSettings.settingsBuilder()
.put("cluster.name","myClusterName").build();
Client client = newTransportClient(settings);
你可以设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中,这样做的好处是一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。代码实例如下:
Settings settings = ImmutableSettings.settingsBuilder()
.put("client.transport.sniff", true).build();
TransportClientclient = new TransportClient(settings);
常见问题
ip问题
当ES服务器监听使用内网服务器IP而访问使用外网IP时,不要使用client.transport.sniff为true,在自动发现时会使用内网IP进行通信,导致无法连接到ES服务器,而直接使用addTransportAddress方法进行指定ES服务器。
版本问题
使用的elasticsearch 5.4.0版本,API使用的5.2.1,client.transport.sniff = true ,连接和查询正常
使用的elasticsearch 5.4.0版本,API使用的5.4.0,client.transport.sniff = true ,查询时报出异常
NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{wat5bi2WRfCrWZVi7NeHiw}{192.168.158.73}{192.168.158.73:9300}]
]
at org.elasticsearch.client.transport.TransportClientNodesService.ensureNodesAreAvailable(TransportClientNodesService.java:348)
at org.elasticsearch.client.transport.TransportClientNodesService.execute(TransportClientNodesService.java:246)
at org.elasticsearch.client.transport.TransportProxyClient.execute(TransportProxyClient.java:59)
at org.elasticsearch.client.transport.TransportClient.doExecute(TransportClient.java:366)
at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:408)
at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:80)
at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:54)
at com.llwwlql.LocalESTest.queryDspReport(LocalESTest.java:228)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
原因是client没有连接上,当把client.transport.sniff = false的时候,可以正常连接和查询。也就是说,API 5.4.0 可能会出现这个问题,具体原因还不清楚。
- 处理方式:client.transport.sniff = false 就无法自动搜索到集群中的其他节点,所以,需要将节点手动添加到client中。
public TransportClient transportClient() {
Settings settings;
if (StringUtils.isEmpty(clustername)) {
settings = Settings.builder().build();
} else {
settings = Settings.builder().put("cluster.name", clustername).build();
}
TransportClient client = new PreBuiltTransportClient(settings);
//设置集群节点
List<NodeConf> nodeConfList = getNodeConfList(eshost);
for (NodeConf nodeConf : nodeConfList) {
try {
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(nodeConf.getIp()), nodeConf.getPort()));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
return client;
}