明天的太阳

导航

Elasticsearch 8.7.1 with Spring

Elasticsearch是一个基于Lucene的搜索引擎,提供了分布式、多租户的全文搜索引擎功能。它可以快速地存储、搜索和分析大量数据,适用于各种类型的应用程序,如日志分析、实时搜索等。

使用Docker启动Elasticsearch & Kibana

运行命令启动Elasticsearch

docker run --name elasticsearch --net example-elastic-network -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -t docker.elastic.co/elasticsearch/elasticsearch:8.7.1

成功后会提示

✅ Elasticsearch security features have been automatically configured!
✅ Authentication is enabled and cluster connections are encrypted.

ℹ️  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
   这是密码

ℹ️  HTTP CA certificate SHA-256 fingerprint:
  74226f5fe0e9faefbe2b3d7f696fe1157979f164344081537679d681bd5c98a0

ℹ️  Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
  这是Kibana的token

ℹ️ Configure other nodes to join this cluster:
• Copy the following enrollment token and start new Elasticsearch nodes with `bin/elasticsearch --enrollment-token <token>` (valid for the next 30 minutes):
  这是配置其他节点用的token

   If you re running in Docker, copy the enrollment token and run:
     `docker run -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.7.1`

运行命令启动Kibana

docker run --name kibana --net example-elastic-network -p 5601:5601 docker.elastic.co/kibana/kibana:8.7.1

成功后会提示如下信息

...
i Kibana has not been configured.

Go to http://0.0.0.0:5601/?code=794975 to get started.
...

这个链接如果不行换成将ip地址改为localhost试试。

Kibana是Elasticsearch的可视化工具,以图表、表格和地图等形式轻松地分析和可视化Elasticsearch中存储的数据。

代码部分

在Spring Boot中使用Elasticsearch可以通过Spring Data Elasticsearch来实现。以下是一个简单的示例代码,演示如何在Spring Boot中使用Elasticsearch:

  1. 添加Elasticsearch依赖
    pom.xml文件中添加以下依赖项:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    
  2. 配置application.properties
    application.properties文件中添加以下配置项:

    # 当设置为true时,Spring会自动扫描应用程序中的@Repository注解,并创建相应的Elasticsearch存储库实例。
    spring.data.elasticsearch.repositories.enabled=true
    
  3. 添加Java配置

    @Configuration
    public class ClientConfig {
        @Value("${es.hosts}")
        private String hosts;
        @Value("${es.name:elastic}")
        private String name;
        @Value("${es.password}")
        private String password;
    
        @Bean
        public ElasticsearchClient docqaElasticsearchClient() {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(name, password));
            List<HttpHost> httpHosts = new ArrayList<>();
            String[] split = hosts.split(",");
            for (String s : split) {
                httpHosts.add(HttpHost.create(s));
            }
            HttpHost[] httpHosts1 = httpHosts.toArray(new HttpHost[0]);
            SSLContext sslContext;
            try {
                sslContext = readCrtFile("src/main/resources/elastic.crt");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            RestClient client = RestClient
                .builder(httpHosts1)
                .setHttpClientConfigCallback(httpAsyncClientBuilder ->
                        httpAsyncClientBuilder.setSSLContext(sslContext).setDefaultCredentialsProvider(credentialsProvider).setKeepAliveStrategy((response, context) -> 180 * 1000))
                .build();
    
            ElasticsearchTransport transport = new RestClientTransport(client, new JacksonJsonpMapper());
            return new ElasticsearchClient(transport);
        }
    
        public static SSLContext readCrtFile(String crtFilePath) throws Exception {
            // 读取crt文件
            InputStream inputStream = new FileInputStream(crtFilePath);
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
    
            // 创建KeyStore并将crt文件添加到KeyStore中
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setCertificateEntry("cert", certificate);
    
            // 创建TrustManagerFactory并初始化KeyStore
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
    
            // 创建KeyManagerFactory并初始化KeyStore
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, null);
    
            // 创建SSLContext并初始化TrustManager和KeyManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
    
            return sslContext;
        }
    }
    

    注意!注意!注意!
    Elastic使用了https,而本地的jdk\lib\security\cacerts中没有对应certification,会导致链接时报错,

    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    ...
    unable to find valid certification path to requested target
    

    所以要通过访问https://localhost:9200使用浏览器导出Elastic的证书。
    下面列出两种方法解决:

    • 使用命令将下载的.crt文件信息导入到本地的cacerts中: keytool -keystore path\to\jdk\cacerts -import -alias xxCert -file "path\to\xx.crt"
    • 通过上述readCrtFile方法加载crt信息。
  4. 创建实体类
    创建一个Java类,用于映射Elasticsearch索引中的文档。例如:

    @Data
    @Document(indexName = "employee")
    public class Employee {
        @Id
        private String id;
        private String firstName;
        private String lastName;
        private String department;
        // Getters and setters
    }
    
  5. 创建Elasticsearch存储库
    创建一个接口,扩展ElasticsearchRepository接口,用于访问Elasticsearch索引。例如:

    // ElasticsearchRepository类中有定义好的很多方法
    public interface EmployeeRepository extends ElasticsearchRepository<Employee, String> {}
    
  6. 使用Elasticsearch存储库

    @RestController
    @RequestMapping("/api/employees")
    public class EmployeeController {
        // 使用自动注入的`MyDocumentRepository`访问Elasticsearch
        @Autowired
        private EmployeeRepository repository;
       
        @PostMapping
        public Employee create(@RequestBody Employee employee) {
            return repository.save(employee);
        }
        @GetMapping("/{id}")
        public Optional<Employee> findById(@PathVariable String id) {
            return repository.findById(id);
        }
    
        @GetMapping
        public Iterable<Employee> findAll() {
            return repository.findAll();
        }
    
        @PutMapping("/{id}")
        public Employee update(@PathVariable String id, @RequestBody Employee employee) {
            employee.setId(id);
            return repository.save(employee);
        }
    
        @DeleteMapping("/{id}")
        public void delete(@PathVariable String id) {
            repository.deleteById(id);
        }
    }
    

posted on 2023-11-15 20:12  东方来客  阅读(23)  评论(0编辑  收藏  举报