本文基於Java High Level REST Client 7.x版本,為您介紹Elasticsearch Java API的用法。
準備工作
建立Elasticsearch執行個體,版本要求大於等於Java High Level REST Client的版本。
本文建立一個7.x版本的執行個體,建立方法請參見建立Elasticsearch執行個體。
說明High Level Client能夠向上相容,例如7.10版本的Java High Level REST Client能確保與7.10及以上版本的Elasticsearch叢集通訊。為了保證最大程度地使用新版用戶端的特性,推薦High Level Client版本與叢集版本一致。
開啟Elasticsearch執行個體的自動建立索引功能。
具體操作步驟請參見配置YML參數。
如果未開啟會提示如下報錯。
配置Elasticsearch執行個體的白名單,確保網路互連。
如果運行Java代碼的伺服器在公網環境下,可通過Elasticsearch執行個體的公網地址進行連通。連通前,需要開啟Elasticsearch執行個體的公網地址,並修改公網地址訪問白名單,將伺服器的公網IP地址加入白名單中。具體操作步驟請參見配置執行個體公網或私網訪問白名單。
重要如果您的用戶端處在家用網路或公司區域網路中,您需要將區域網路的公網出口IP地址添加到白名單中,而非用戶端機器的內網地址。
您也可以將白名單配置為0.0.0.0/0,允許所有IPv4地址訪問Elasticsearch執行個體。此配置會導致執行個體完全暴露在公網中,增加安全風險,配置前請確認您是否可以接受這個風險。
如果未配置白名單或白名單配置錯誤,系統會提示連線逾時報錯(Timeout connecting)。
如果您需要通過用戶端訪問Kibana節點,還需要配置Kibana的訪問白名單,詳細資料請參見配置Kibana公網或私網訪問白名單。
如果運行Java代碼的伺服器與Elasticsearch執行個體在同一Virtual Private Cloud(Virtual Private Cloud)中,可通過Elasticsearch執行個體的私網地址進行連通。連通前,需要確保VPC私網訪問白名單(預設為0.0.0.0/0)中已添加了伺服器的內網IP地址。
安裝Java,要求JDK版本為1.8及以上。
建立Java Maven工程,並將如下的pom依賴添加到Java工程的pom.xml檔案中。
pom依賴
使用時,您需要將pom依賴中的7.x版本號碼替換為具體的版本號碼。
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.x</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
Log4j可能存在遠程代碼執行漏洞,詳細資料請參見漏洞公告 | Apache Log4j2遠程代碼執行漏洞。
樣本
單擊下載完整範例程式碼。
以下代碼使用Index API建立索引,使用Delete API刪除該索引,並示範了在JVM記憶體配置比較有限的用戶端環境中,通過調整ResponseConsumer配置,限制非同步響應所佔用的緩衝的大小。
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class RestClientTest74 {
private static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 預設緩衝限制為100MB,此處修改為30MB。
builder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory
.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
public static void main(String[] args) {
// Elasticsearch叢集需要basic auth驗證。
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
//訪問使用者名稱和密碼為您建立Elasticsearch執行個體時設定的使用者名稱和密碼,也是Kibana控制台的登入使用者名稱和密碼。
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("{訪問使用者名稱}", "{訪問密碼}"));
// 通過builder建立rest client,配置http client的HttpClientConfigCallback。
// 單擊所建立的Elasticsearch執行個體ID,在基本資料頁面擷取公網地址,即為ES叢集地址。
RestClientBuilder builder = RestClient.builder(new HttpHost("{ES叢集地址}", 9200, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
// RestHighLevelClient執行個體通過REST high-level client builder進行構造。
RestHighLevelClient highClient = new RestHighLevelClient(builder);
try {
// 建立request。
Map<String, Object> jsonMap = new HashMap<>();
// field_01、field_02為欄位名,value_01、value_02為對應的值。
jsonMap.put("{field_01}", "{value_01}");
jsonMap.put("{field_02}", "{value_02}");
//index_name為索引名稱;type_name為類型名稱,7.0及以上版本必須為_doc;doc_id為文檔的id。
IndexRequest indexRequest = new IndexRequest("{index_name}", "_doc", "{doc_id}").source(jsonMap);
// 同步執行,並使用自訂RequestOptions(COMMON_OPTIONS)。
IndexResponse indexResponse = highClient.index(indexRequest, COMMON_OPTIONS);
long version = indexResponse.getVersion();
System.out.println("Index document successfully! " + version);
//index_name為索引名稱;type_name為類型名稱,7.0及以上版本必須為_doc;doc_id為文檔的id。與以上建立索引的名稱和id相同。
DeleteRequest request = new DeleteRequest("{index_name}", "_doc", "{doc_id}");
DeleteResponse deleteResponse = highClient.delete(request, COMMON_OPTIONS);
System.out.println("Delete document successfully! \n" + deleteResponse.toString());
highClient.close();
} catch (IOException ioException) {
// 異常處理。
}
}
}
以上範例程式碼中帶{}
的參數需要替換為您具體業務的參數,詳情請參見代碼注釋。
若為高並發情境,需要增加用戶端串連數,具體配置如下。
httpClientBuilder.setMaxConnTotal(500);
httpClientBuilder.setMaxConnPerRoute(300);
串連程式碼範例:
String host = "127.0.0.1";
int port = 9200;
String username = "elastic";
String password = "passwd";
final int max_conn_total = 500;
final int max_conn_per_route = 300;
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost( host, 9200, "http")).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.setMaxConnTotal(max_conn_total);
httpClientBuilder.setMaxConnPerRoute(max_conn_per_route);
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
);
更多Java High Level REST Client的使用特性,請參見Java High Level REST Client官方文檔。