• 使用Java客户端操作elasticsearch(二)


    承接上文,使用Java客户端操作elasticsearch,本文主要介绍 常见的配置 和Sniffer(集群探测) 的使用。

    常见的配置

    前面已介绍过,RestClientBuilder支持同时提供一个RequestConfigCallback和一个HttpClientConfigCallback,你可以定制 the Apache Async Http Client 公开的配置。这两个回调函数可以修改某些特定的行为,而不会覆盖RestClient初始化的所有其他默认配置。 本节介绍一些需要为客户端进行额外配置的常见场景。

    Timeouts

    啥都不说了,直接上代码。该例子演示了连接超时(默认为1秒)和套接字超时(默认为30秒)。 也相应地调整最大重试超时时间(默认为30秒)。

    RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
            .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
                //该方法接收一个RequestConfig.Builder对象,对该对象进行修改后然后返回。 
                @Override
                public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                    return requestConfigBuilder.setConnectTimeout(5000) //连接超时(默认为1秒)
                            .setSocketTimeout(60000);//套接字超时(默认为30秒)
                }
            })
            .setMaxRetryTimeoutMillis(60000);//调整最大重试超时时间(默认为30秒)

    线程数

    The Apache Http Async Client默认启动一个dispatcher线程和供连接管理器使用的多个worker线程,与本地检测到的处理器数量一样多(取决于Runtime.getRuntime().availableProcessors()的返回值)。 修改线程数可以如下操作:

    RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setDefaultIOReactorConfig(
                            IOReactorConfig.custom().setIoThreadCount(1).build());
                }
            });   

    基本认证

    同样直接上代码

    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials("user", "password"));
    
    RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                // 该方法接收HttpAsyncClientBuilder的实例作为参数,对其修改后进行返回
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);//提供一个默认凭据
                }
            });

    抢占式认证可以被禁用,这意味着每个请求都将被发送,不用去看授权请求头,在收到HTTP 401响应后,会再次发送相同的请求,这次会带上基本的身份认证头,如果你想这样做,那么你可以通过HttpAsyncClientBuilder来禁用它:

    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials("user", "password"));
    
    RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    httpClientBuilder.disableAuthCaching(); //禁用抢占式身份验证
                    return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
            });  

    加密通信

    加密通信也可以通过HttpClientConfigCallback进行配置。 参数HttpAsyncClientBuilder公开了配置加密通信的多种方法:

    setSSLContext,setSSLSessionStrategy和setConnectionManager,重要性依次增加。 以下是一个例子:
    KeyStore truststore = KeyStore.getInstance("jks");
    try (InputStream is = Files.newInputStream(keyStorePath)) {
        truststore.load(is, keyStorePass.toCharArray());
    }
    SSLContextBuilder sslBuilder = SSLContexts.custom().loadTrustMaterial(truststore, null);
    final SSLContext sslContext = sslBuilder.build();
    RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setSSLContext(sslContext);
                }
            });

    如果未提供明确的配置,则将使用系统默认配置

    其他

    如果对其他配置需要修改,可以参考Apache HttpAsyncClient文档:https://hc.apache.org/httpcomponents-asyncclient-4.1.x/ 

    如果您的应用程序在安全管理器下运行,可能会采用JVM默认缓存策略:

    • A. 域名能够正确解析的IP地址将会永久缓存;
    • B. 域名解析出错的IP地址会默认缓存10S;

    如果客户端连接到的主机的地址随时间变化,那么可能你想修改默认的JVM行为。这些可以通过添加 networkaddress.cache.ttl=<timeout> 和 networkaddress.cache.negative.ttl=<timeout>  到您的Java安全策略进行修改。

    嗅探器

    从运行的Elasticsearch集群中自动发现节点,并将其设置到现有的RestClient实例。 默认情况下,它将使用Nodes Info api来检索属于集群的节点,并使用jackson解析响应的json数据。看完之后还是不清除说的个啥?那就仔细说说吧。之前我们都是像下面这样创建客户端实例的。

    RestClient restClient = RestClient.builder(
                    new HttpHost("localhost", 9200, "http"),
                    new HttpHost("localhost", 9201, "http")).build();

    假设一个集群有100个节点,如果手动 new HttpHost("localhost", 9200, "http") 这样创建100个HttpHost也可以,但是可能会写到手软,出错概率极大。所以就出现了sniffer,它来帮你做这件事。

    the REST client sniffer 兼容Elasticsearch 2.x及以上版本。可以在这里找到它的javadoc。

    Maven仓库

    The REST client sniffer 与Elasticsearch的发布周期相同。 发布的第一版为5.0.0-alpha4。同样,你也可以自由替换成你想要的版本。 它和通讯的Elasticsearch版本之间没有关联。sniffer 支持从Elasticsearch 2.x及其以后的版本获取节点列表。

    Maven配置

    以下是使用maven作为依赖管理器。 将以下内容添加到您的pom.xml文件中:

    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client-sniffer</artifactId>
        <version>6.2.3</version>
    </dependency>

    Gradle配置

    以下是使用gradle作为依赖管理器。 将以下内容添加到您的build.gradle文件中:

    dependencies {
        compile 'org.elasticsearch.client:elasticsearch-rest-client-sniffer:6.2.3'
    }

    用法

     RestClient实例创建后,就可以将一个Sniffer关联到它。Sniffer使用RestClient定期(默认每5分钟)从集群中获取当前所有节点的列表,并通过调用RestClient的setHosts方法来更新。

    RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200, "http"))
            .build();
    Sniffer sniffer = Sniffer.builder(restClient).build();

    关闭Sniffer是非常重要的,这样它的后台线程才能正常关闭并释放所有资源。 Sniffer对象的生命周期应与RestClient相同,并在客户端之前关闭:

    sniffer.close();
    restClient.close();

    Sniffer默认每5分钟更新一次节点。 该时间间隔也可以自定义(以毫秒为单位),如下所示:

    RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200, "http"))
            .build();
    Sniffer sniffer = Sniffer.builder(restClient)
            .setSniffIntervalMillis(60000).build();

    也可以在失败时启用嗅探,这意味着在每次失败后,节点列表将被直接更新。 此种方式需要首先创建SniffOnFailureListener,并在创建RestClient时提供。 同样,一旦Sniffer被创建,它需要与同一个SniffOnFailureListener实例相关联,SniffOnFailureListener实例将在每次失败时通知,并且会使用该Sniffer再执行一轮嗅探。

    Elasticsearch Nodes Info api在连接到节点时不会返回使用的协议,而只会返回它们的host:port键对,因此默认情况下使用http。 如果想使用https,则必须手动创建ElasticsearchHostsSniffer实例,可按如下方式:

    RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200, "http"))
            .build();
    HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer(
            restClient,
            ElasticsearchHostsSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT,
            ElasticsearchHostsSniffer.Scheme.HTTPS);
    Sniffer sniffer = Sniffer.builder(restClient)
            .setHostsSniffer(hostsSniffer).build();

    同样也可以自定义sniffRequestTimeout,默认为1秒。 在调用the Nodes Info api时timeout参数使用querystring方式传递,以便当服务器端的超时时,仍然会返回有效的响应,尽管它可能只包含群集一部分的节点 。

    RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200, "http"))
            .build();
    HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer(
            restClient,
            TimeUnit.SECONDS.toMillis(5),
            ElasticsearchHostsSniffer.Scheme.HTTP);
    Sniffer sniffer = Sniffer.builder(restClient)
            .setHostsSniffer(hostsSniffer).build();

    此外,我们可能需要从外部源获取主机,而不是从Elasticsearch获取主机。则可以自定义实现HostsSniffer。

     RestClient restClient = RestClient.builder(
                    new HttpHost("localhost", 9200, "http"))
                    .build();
            HostsSniffer hostsSniffer = new HostsSniffer() {
                @Override
                public List<HttpHost> sniffHosts() throws IOException {
                    return null;//从外部获取主机
                }
            };
            Sniffer sniffer = Sniffer.builder(restClient)
                    .setHostsSniffer(hostsSniffer).build();

    官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_common_configuration.html

  • 相关阅读:
    Lazarus教程 中文版后续给出
    QBASIC教程
    Object Pascal中文手册 经典教程
    Pascal 基础教程
    Delphi中的关键字与保留字
    Pascal数据结构与算法
    Pascal小游戏 贪吃蛇
    Pascal小游戏 俄罗斯方块怀旧版
    Pascal ASCII和文本的转换
    IDEA安装问题解决
  • 原文地址:https://www.cnblogs.com/ginb/p/8696090.html
Copyright © 2020-2023  润新知