正如初始化中所解釋的,RestClientBuilder
支持提供RequestConfigCallback
和HttpClientConfigCallback
,它們容許Apache Async Http Client公開的任何自定義。這些回調能夠修改客戶端的某些特定行爲,而不會覆蓋RestClient
初始化的全部其餘默認配置,本節介紹一些須要爲低級別Java REST Client進行其餘配置的常見方案。html
配置請求超時能夠經過在經過其構建器構建RestClient
時提供RequestConfigCallback
實例來完成,該接口有一個方法接收org.apache.http.client.config.RequestConfig.Builder的實例做爲參數並具備相同的返回類型,能夠修改請求配置構建器,而後返回。在如下示例中,咱們將增長鏈接超時(默認爲1秒)和socket超時(默認爲30秒),咱們也相應地調整最大重試超時(默認爲30秒)。java
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()
的返回),線程數能夠修改以下:node
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
客戶端構建器,而後返回。在如下示例中,咱們設置了須要基自己份驗證的默認憑據提供程序。apache
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); } });
能夠禁用搶佔式身份驗證,這意味着每一個請求都將在沒有受權標頭的狀況下發送,以查看是否接受該請求,而且在接收到HTTP401
響應後,將從新發送與基自己份驗證標頭徹底相同的請求,若是你但願這樣作,那麼你能夠經過HttpAsyncClientBuilder
禁用它:segmentfault
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();
— 禁用搶佔式身份驗證。api
也能夠經過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/。oracle
若是你的應用程序在安全管理器下運行,則可能會受到JVM默認策略的限制,即無限期緩存正主機名解析和負主機名解析10秒,若是你鏈接客戶端的主機的已解析地址隨時間變化,那麼你可能但願修改默認的JVM行爲,能夠經過將 networkaddress.cache.ttl=<timeout>和 networkaddress.cache.negative.ttl=<timeout>添加到 Java安全策略來修改這些。
客戶端以循環方式將每一個請求發送到其中一個配置的節點,能夠選擇經過初始化客戶端時須要提供的節點選擇器來過濾節點,這在啓用嗅探時頗有用,以防只有HTTP請求才能觸發專用主節點。對於每一個請求,客戶端將運行最終配置的節點選擇器以過濾候選節點,而後從剩餘的節點中選擇列表中的下一個節點。socket
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中沒有任何節點可用時強制恢復本地節點。
不一致地選擇相同節點集的節點選擇器將使循環行爲變得不可預測而且可能不公平,上面的偏好示例很好,由於它能夠解釋已經影響輪詢調度可預測性的節點的可用性,節點選擇不該該依賴於其餘外部因素,不然輪詢調度將沒法正常工做。