使用Java客戶端操做elasticsearch(二)

承接上文,使用Java客戶端操做elasticsearch,本文主要介紹 常見的配置 和Sniffer(集羣探測) 的使用。html

常見的配置

前面已介紹過,RestClientBuilder支持同時提供一個RequestConfigCallback和一個HttpClientConfigCallback,你能夠定製 the Apache Async Http Client 公開的配置。這兩個回調函數能夠修改某些特定的行爲,而不會覆蓋RestClient初始化的全部其餘默認配置。 本節介紹一些須要爲客戶端進行額外配置的常見場景。java

Timeouts

啥都不說了,直接上代碼。該例子演示了鏈接超時(默認爲1秒)和套接字超時(默認爲30秒)。 也相應地調整最大重試超時時間(默認爲30秒)。apache

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()的返回值)。 修改線程數能夠以下操做:json

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());
            }
        });   

基本認證

一樣直接上代碼api

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/ oracle

若是您的應用程序在安全管理器下運行,可能會採用JVM默認緩存策略:async

  • 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

相關文章
相關標籤/搜索