client.transport.sniff的使用方法与一些常见错误

通过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 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;
    }
微信公众号欢迎关注.jpg

你可能感兴趣的:(client.transport.sniff的使用方法与一些常见错误)