天天看點

Elasticsearch Java Low Level REST Client(通用配置)Elasticsearch Java Low Level REST Client(通用配置)

Elasticsearch Java Low Level REST Client(通用配置)

通用配置

正如初始化中所解釋的,

RestClientBuilder

支援提供

RequestConfigCallback

HttpClientConfigCallback

,它們允許Apache Async Http Client公開的任何自定義。這些回調可以修改用戶端的某些特定行為,而不會覆寫

RestClient

初始化的所有其他預設配置,本節介紹一些需要為低級别Java REST Client進行其他配置的常見方案。

逾時

配置請求逾時可以通過在通過其建構器建構

RestClient

時提供

RequestConfigCallback

執行個體來完成,該接口有一個方法接收org.apache.http.client.config.RequestConfig.Builder的執行個體作為參數并具有相同的傳回類型,可以修改請求配置建構器,然後傳回。在以下示例中,我們将增加連接配接逾時(預設為1秒)和socket逾時(預設為30秒),我們也相應地調整最大重試逾時(預設為30秒)。

RestClientBuilder builder = RestClient.builder(
    new HttpHost("localhost", 9200))
    .setRequestConfigCallback(
        new RestClientBuilder.RequestConfigCallback() {
            @Override
            public RequestConfig.Builder customizeRequestConfig(
                    RequestConfig.Builder requestConfigBuilder) {
                return requestConfigBuilder
                    .setConnectTimeout(5000)
                    .setSocketTimeout(60000);
            }
        })
    .setMaxRetryTimeoutMillis(60000);
           

線程數

Apache Http Async Client預設啟動一個排程線程,以及連接配接管理器使用的許多工作線程,與本地檢測到的處理器數量一樣多(取決于

Runtime.getRuntime().availableProcessors()

的傳回),線程數可以修改如下:

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

基本認證

配置基本身份驗證可以通過在通過其建構器建構

RestClient

時提供

HttpClientConfigCallback

來完成,該接口有一個方法接收org.apache.http.impl.nio.client.HttpAsyncClientBuilder的執行個體作為參數并具有相同的傳回類型,可以修改

http

用戶端建構器,然後傳回。在以下示例中,我們設定了需要基本身份驗證的預設憑據提供程式。

final CredentialsProvider credentialsProvider =
    new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
    new UsernamePasswordCredentials("user", "password"));

RestClientBuilder builder = RestClient.builder(
    new HttpHost("localhost", 9200))
    .setHttpClientConfigCallback(new HttpClientConfigCallback() {
        @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 HttpClientConfigCallback() {
        @Override
        public HttpAsyncClientBuilder customizeHttpClient(
                HttpAsyncClientBuilder httpClientBuilder) {
            httpClientBuilder.disableAuthCaching(); 
            return httpClientBuilder
                .setDefaultCredentialsProvider(credentialsProvider);
        }
    });
           

httpClientBuilder.disableAuthCaching();

 — 禁用搶占式身份驗證。

加密通信

也可以通過

HttpClientConfigCallback

配置加密通信,作為參數接收的org.apache.http.impl.nio.client.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 HttpClientConfigCallback() {
        @Override
        public HttpAsyncClientBuilder customizeHttpClient(
                HttpAsyncClientBuilder httpClientBuilder) {
            return httpClientBuilder.setSSLContext(sslContext);
        }
    });
           

如果未提供顯式配置,則将使用系統預設配置。

其他

對于所需的任何其他必需配置,應參考Apache HttpAsyncClient文檔:https://hc.apache.org/httpcomponents-asyncclient-4.1.x/。

如果你的應用程式在安全管理器下運作,則可能會受到JVM預設政策的限制,即無限期緩存正主機名解析和負主機名解析10秒,如果你連接配接用戶端的主機的已解析位址随時間變化,那麼你可能希望修改預設的JVM行為,可以通過将 networkaddress.cache.ttl=<timeout>和 networkaddress.cache.negative.ttl=<timeout>添加到 Java安全政策來修改這些。

節點選擇器

用戶端以循環方式将每個請求發送到其中一個配置的節點,可以選擇通過初始化用戶端時需要提供的節點選擇器來過濾節點,這在啟用嗅探時很有用,以防隻有HTTP請求才能觸發專用主節點。對于每個請求,用戶端将運作最終配置的節點選擇器以過濾候選節點,然後從剩餘的節點中選擇清單中的下一個節點。

RestClientBuilder builder = RestClient.builder(
        new HttpHost("localhost", 9200, "http"));
builder.setNodeSelector(new NodeSelector() { 
    @Override
    public void select(Iterable<Node> nodes) {
        /*
         * Prefer any node that belongs to rack_one. If none is around
         * we will go to another rack till it's time to try and revive
         * some of the nodes that belong to rack_one.
         */
        boolean foundOne = false;
        for (Node node : nodes) {
            String rackId = node.getAttributes().get("rack_id").get(0);
            if ("rack_one".equals(rackId)) {
                foundOne = true;
                break;
            }
        }
        if (foundOne) {
            Iterator<Node> nodesIt = nodes.iterator();
            while (nodesIt.hasNext()) {
                Node node = nodesIt.next();
                String rackId = node.getAttributes().get("rack_id").get(0);
                if ("rack_one".equals(rackId) == false) {
                    nodesIt.remove();
                }
            }
        }
    }
});
           

設定配置設定感覺節點選擇器,允許選擇本地rack中的節點(如果有),否則轉到任何rack中的任何其他節點。它充當偏好而不是嚴格的要求,如果沒有任何本地節點可用,它将進入另一個rack,而不是在這種情況下不傳回任何節點,這将使用戶端在首選rack中沒有任何節點可用時強制恢複本地節點。

不一緻地選擇相同節點集的節點選擇器将使循環行為變得不可預測并且可能不公平,上面的偏好示例很好,因為它可以解釋已經影響輪詢排程可預測性的節點的可用性,節點選擇不應該依賴于其他外部因素,否則輪詢排程将無法正常工作。