springboot集成elk 三:springboot + Elasticsearch Rest-Client


注:  該集成方式,對Elasticsearch無版本限制,但是需要自行封裝請求,解析結果等。

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

<dependency>
   <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.47</version>
</dependency>

 

客戶端配置RestConfig 

@Configuration

public class RestConfig {

    @Bean

    public RestClient getClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        // 如果有多個從節點可以持續在內部new多個HttpHost,參數1是ip,參數2是HTTP端口,參數3是通信協議

        RestClientBuilder clientBuilder = RestClient.builder(new HttpHost("134.175.237.32", 9200, "http"));

 

        // 添加其他配置,返回來的還是RestClientBuilder對象,這些配置都是可選的

 

        //【1. 設置請求頭】 設置請求頭,每個請求都會帶上這個請求頭

        //Header[] defaultHeaders = {new BasicHeader("header", "value")};

        //clientBuilder.setDefaultHeaders(defaultHeaders);

        Header[] defaultHeaders = {new BasicHeader("charset", "utf-8"),

                new BasicHeader("content-type", "application/json")};

        clientBuilder.setDefaultHeaders(defaultHeaders);

 

        //【2. 設置超時時間】 設置超時時間,多次嘗試同一請求時應該遵守的超時。默認值為30秒,與默認套接字超時相同。若自定義套接字超時,則應相應地調整最大重試超時

        //clientBuilder.setMaxRetryTimeoutMillis(60000);

 

        //【3. 設置節點失敗監聽器】設置監聽器,每次節點失敗都可以監聽到,可以作額外處理

        /*clientBuilder.setFailureListener(new RestClient.FailureListener() {

            @Override

            public void onFailure(Node node) {

                super.onFailure(node);

                System.out.println(node.getName() + "==節點失敗了");

            }

        });*/

 

        /*【4. 設置節點選擇器】 配置節點選擇器,客戶端以循環方式將每個請求發送到每一個配置的節點上,

        發送請求的節點,用於過濾客戶端,將請求發送到這些客戶端節點,默認向每個配置節點發送,

        這個配置通常是用戶在啟用嗅探時向專用主節點發送請求(即只有專用的主節點應該被HTTP請求命中)

        */

       // clientBuilder.setNodeSelector(NodeSelector.SKIP_DEDICATED_MASTERS);

 

        // 進行詳細的配置

       /* clientBuilder.setNodeSelector(new NodeSelector() {

            // 設置分配感知節點選擇器,允許選擇本地機架中的節點(如果有),否則轉到任何機架中的任何其他節點。

            @Override

            public void select(Iterable<Node> nodes) {

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

                        }

                    }

                }

            }

        });*/

 

       /* 【5. 配置HTTP異步請求ES的線程數】

       配置異步請求的線程數量,Apache Http Async Client默認啟動一個調度程序線程,以及由連接管理器使用的許多工作線程

        (與本地檢測到的處理器數量一樣多,取決於Runtime.getRuntime().availableProcessors()返回的數量)。線程數可以修改如下,

        這里是修改為1個線程,即默認情況

        */

        /*clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {

            @Override

            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {

                return httpAsyncClientBuilder.setDefaultIOReactorConfig(

                        IOReactorConfig.custom().setIoThreadCount(1).build()

                );

            }

        });*/

 

        /*【6. 配置連接超時和套接字超時】

        配置請求超時,將連接超時(默認為1秒)和套接字超時(默認為30秒)增加,

        這里配置完應該相應地調整最大重試超時(默認為30秒),即上面的setMaxRetryTimeoutMillis,一般於最大的那個值一致即60000

        */

       /* clientBuilder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {

            @Override

            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {

                // 連接5秒超時,套接字連接60s超時

                return requestConfigBuilder.setConnectTimeout(5000).setSocketTimeout(60000);

            }

        });*/

 

       /*【7. 配置ES安全認證】

        如果ES設置了密碼,那這里也提供了一個基本的認證機制,下面設置了ES需要基本身份驗證的默認憑據提供程序

            */

        /*final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

        credentialsProvider.setCredentials(AuthScope.ANY,

                new UsernamePasswordCredentials("user", "password"));

        clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {

            @Override

            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {

                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);

            }

        });*/

 

        /*

        上面采用異步機制實現搶先認證,這個功能也可以禁用,這意味着每個請求都將在沒有授權標頭的情況下發送,然后查看它是否被接受,

        並且在收到HTTP 401響應后,它再使用基本認證頭重新發送完全相同的請求,這個可能是基於安全、性能的考慮

         */

        /*clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {

            @Override

            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {

                // 禁用搶先認證的方式

                httpClientBuilder.disableAuthCaching();

                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);

            }

        });*/

 

 

        /* 【8. 配置通信加密】

        配置通信加密,有多種方式: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();

        clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {

            @Override

            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {

                return httpClientBuilder.setSSLContext(sslContext);

            }

        });*/

        // 最后配置好的clientBuilder再build一下即可得到真正的Client

        return clientBuilder.build();

    }

}

 


實體類: 

public class Book {

    private String id;

    private String name;

    private String author;

 

    public String getAuthor() {

        return author;

    }

 

    public void setAuthor(String author) {

        this.author = author;

    }

 

    public String getId() {

        return id;

    }

 

    public void setId(String id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    @Override

    public String toString() {

        return "Book{" +

                "id=" + id +

                ", name='" + name + '\'' +

                '}';

    }

}

 


Rest  Controller: 

@RestController

@RequestMapping("/book")

public class BookController {

    @Autowired

    private RestClient client;

 

 

    /**新增

     * 添加ES對象, Book的ID就是ES中存儲的document的ID,所以最好不要為空,自定義生成的ID太浮誇

     *

     * @return ResponseEntity

     * @throws IOException

     */

    @PostMapping("/add")

    public ResponseEntity<String> add(Book book) throws IOException {

        // 構造HTTP請求,第一個參數是請求方法,第二個參數是服務器的端點,host默認是http://localhost:9200,

        // endpoint直接指定為index/type的形式

        Request request = new Request("POST", new StringBuilder("/test_db/book/").

                append(book.getId()).toString());

        // 設置其他一些參數比如美化json

        request.addParameter("pretty", "true");

 

        String bookString=JSON.toJSONString(book);

        System.out.println(bookString);

 

        // 設置請求體並指定ContentType,如果不指定默認為APPLICATION_JSON

        request.setEntity(new NStringEntity(bookString, ContentType.APPLICATION_JSON));

 

        // 發送HTTP請求

        Response response = client.performRequest(request);

 

        // 獲取響應體, id: AWXvzZYWXWr3RnGSLyhH

        String responseBody = EntityUtils.toString(response.getEntity());

        return new ResponseEntity<>(responseBody, HttpStatus.OK);

    }

 

    /**

     * 根據id獲取ES對象

     *

     * @param id

     * @return

     * @throws IOException

     */

    @GetMapping("/getBookById/{id}")

    public ResponseEntity<String> getBookById(@PathVariable("id") String id) {

        Request request = new Request("GET", new StringBuilder("/test_db/book/").

                append(id).toString());

        // 添加json返回優化

        request.addParameter("pretty", "true");

        Response response = null;

        String responseBody = null;

        try {

            // 執行HHTP請求

            response = client.performRequest(request);

            responseBody = EntityUtils.toString(response.getEntity());

        } catch (IOException e) {

            return new ResponseEntity<>("can not found the book by your id", HttpStatus.NOT_FOUND);

        }

        return new ResponseEntity<>(responseBody, HttpStatus.OK);

    }

 

    /**

     * 根據id更新Book

     *

     * @param id

     * @param book

     * @return

     */

    @PostMapping("/updateBook/{id}")

    public ResponseEntity<String> updateBook(@PathVariable("id") String id, Book book) throws IOException {

        // 構造HTTP請求

        Request request = new Request("POST", new StringBuilder("/test_db/book/").

                append(id).append("/_update").toString());

        request.addParameter("pretty", "true");

 

        // 將數據丟進去,這里一定要外包一層“doc”,否則內部不能識別

        JSONObject jsonObject = new JSONObject();

        jsonObject.put("doc", book);

        request.setEntity(new NStringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON));

 

        // 執行HTTP請求

        Response response = client.performRequest(request);

 

        // 獲取返回的內容

        String responseBody = EntityUtils.toString(response.getEntity());

 

        return new ResponseEntity<>(responseBody, HttpStatus.OK);

    }

 

    /**

     * 使用腳本更新Book

     * @param id

     * @param

     * @return

     * @throws IOException

     */

    @PostMapping("/update2/{id}")

    public ResponseEntity<String> updateBook2(@PathVariable("id") String id, @RequestParam("name") String name) throws IOException {

        // 構造HTTP請求

        Request request = new Request("POST", new StringBuilder("/test_db/book/").

                append(id).append("/_update").toString());

        request.addParameter("pretty", "true");

 

        JSONObject jsonObject = new JSONObject();

        // 創建腳本語言,如果是字符變量,必須加單引號

        StringBuilder op1 = new StringBuilder("ctx._source.name=").append("'" + name + "'");

        jsonObject.put("script", op1);

 

        request.setEntity(new NStringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON));

 

        // 執行HTTP請求

        Response response = client.performRequest(request);

 

        // 獲取返回的內容

        String responseBody = EntityUtils.toString(response.getEntity());

 

        return new ResponseEntity<>(responseBody, HttpStatus.OK);

    }

 

    @PostMapping("/deleteById/{id}")

    public ResponseEntity<String> deleteById(@PathVariable("id") String id) throws IOException {

        Request request = new Request("DELETE", new StringBuilder("/test_db/book/").append(id).toString());

        request.addParameter("pretty", "true");

        // 執行HTTP請求

        Response response = client.performRequest(request);

        // 獲取結果

        String responseBody = EntityUtils.toString(response.getEntity());

 

        return new ResponseEntity<>(responseBody, HttpStatus.OK);

    }

 

    /**

     * 獲取ES對象列表

     *

     * @return

     * @throws IOException

     */

    @GetMapping("/getBookList")

    public ResponseEntity<Object> getBookList(@RequestParam("author") String author) {

        // 構造HTTP請求

        Request request = new Request("POST", new StringBuilder("/test_db/book/_search").toString());

        // 添加json返回優化

        request.addParameter("pretty", "true");

 

        StringBuilder requestBody = new StringBuilder();

        requestBody.append("{\"size\":10,\"query\":{\"match\":{\"author\":\""+author+"\"}},\"from\": 0,\"_source\": [\"id\", \"name\", \"author\"]}");

 

        //JSONObject jsonObject = new JSONObject();

       // jsonObject.put("doc", requestBody.toString());

 

        request.setEntity(new NStringEntity(requestBody.toString(), ContentType.APPLICATION_JSON));

 

        Response response = null;

        String responseBody = null;

        Object result=null;

        try{

            // 執行HTTP請求

            response = client.performRequest(request);

            // 獲取返回的內容

            responseBody = EntityUtils.toString(response.getEntity());

            Map jsonObject = JSON.parseObject(responseBody);

            result =jsonObject.get("hits");

            System.out.println(result);

        } catch (IOException e) {

            e.printStackTrace();

            return new ResponseEntity<>("can not found the book by your id", HttpStatus.NOT_FOUND);

        }

 

        return new ResponseEntity<>(result, HttpStatus.OK);

    }

 

springboot-elasticsearch-rest-client.zi

p


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM