docker安装elasticsearch8.8.1+kibana,并用java连接
安装es
1,下载镜像
docker pull elasticsearch:8.8.1
查询是否下载成功
docker images
2,创建es网络
docker network create elastic
3,这里不挂载目录,单例模式,先后台启动
启动后可查看日志信息
docker logs -f -t -n=5 elasticsearch
,4,没有明显报错则修改配置文件如下,创建一个本地文件命名为elasticsearch.yml或从容器内拷出
拷出命令
docker cp elasticsearch:/usr/share/elasticsearch/config/elasticsearch.yml /usr/local/es
修改配置文件
拷进容器内 : docker cp /usr/local/es/elasticsearch.yml elasticsearch:/usr/share/elasticsearch/config
重启容器: docker restart elasticsearch
测试连通: curl localhost:9200
4,设置密码
进入es容器内: docker exec -it elasticsearch bash
设置账号密码./bin/elasticsearch-setup-passwords interactive 回车后依次输入各账号的密码
安装kibana
1,下载镜像,注意这里也要下载同样的版本
docker pull kibana:8.8.1
2,启动命令
3,修改配置文件
拷出容器内配置文件: docker cp kibana:/usr/share/kibana/config/kibana.yml /usr/local/kibana
修改为如下
拷进容器: docker cp /usr/local/kibana/kibana.yml kibana:/usr/share/kibana/config
重启: docker restart kibana
此时访问 http://192.168.10.114:5601/app 可查看安装情况
问题处理
1,由于两个容器在docker内是独立的,所以直接连连不通,解决办法有两个
①docker 将elasticsearch的端口映射出来,在es的启动命令中提现
②如果是配置在虚拟机中,则需要找到es的ip,
管理索引
1,打开kibana管理界面,可以看到索引
这里可以使用开发工具创建一个索引
2,java 连接
导入pom
<dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.12.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.12.3</version> </dependency> <dependency> <groupId>jakarta.json</groupId> <artifactId>jakarta.json-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>8.8.1</version> </dependency>
2,添加配置
elasticsearch: host: 192.168.10.114 port: 9200 username: elastic password: elastic apikey: TERaUHVva0IwdzJHQkVYT0doY1A6TEhzVzdGR09RcUd5UDFORGNHWmxvUQ==
3,代码
package com.cfam.quotaplatform.config; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import com.alibaba.cloud.commons.lang.StringUtils; import org.apache.http.Header; 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.message.BasicHeader; import org.elasticsearch.client.RestClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ElasticSearchConfig { @Value("${elasticsearch.host}") private String host; @Value("${elasticsearch.port}") private Integer port; @Value("${elasticsearch.apiKey:}") private String apiKey; @Value("${elasticsearch.username}") private String userName; @Value("${elasticsearch.password}") private String password; @Bean public ElasticsearchClient elasticsearchClient() { ElasticsearchTransport transport; RestClient restClient; if(StringUtils.isNotBlank(apiKey)){ //apiKey验证模式 restClient = RestClient .builder(new HttpHost(host, port)) .setDefaultHeaders(new Header[]{ new BasicHeader("Authorization", "ApiKey " + apiKey)}) .build(); }else{ final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); // 账号密码验证模式 credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password)); restClient = RestClient.builder(new HttpHost(host, port)) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)).build(); } transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); ElasticsearchClient client = new ElasticsearchClient(transport); System.out.println("es初始化完成"); return client; } }
package com.cfam.quotaplatform.service; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.BulkRequest; import co.elastic.clients.elasticsearch.core.BulkResponse; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.transport.endpoints.BooleanResponse; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Service @Log4j2 public class ElasticsearchService<T> { @Resource private ElasticsearchClient elasticsearchClient; /** * 判断索引是否存在. * * @param indexName index名称 */ public boolean existIndex(String indexName) { try { BooleanResponse booleanResponse = elasticsearchClient.indices().exists(e -> e.index(indexName)); return booleanResponse.value(); } catch (IOException e) { log.error("向es中检测索引【{}】出错,错误信息为:{}", indexName, e.getMessage()); throw new RuntimeException("向es中检测索引【"+indexName+"】出错"); } } /** * 创建索引. * * @param indexName index名称 */ public void createIndex(String indexName) { try { elasticsearchClient.indices().create(c -> c.index(indexName)); } catch (IOException e) { log.error("向es中创建索引【{}】出错,错误信息为:{}", indexName, e.getMessage()); } } /** * 添加记录. * */ public void addDocument(String indexName, T data) { try { if (!this.existIndex(indexName)) { this.createIndex(indexName); } elasticsearchClient.index(i -> i.index(indexName).id(null).document(data)); } catch (IOException e) { log.error("向es中添加document出错:{}", e.getMessage()); } } /** * 批量添加. * * @param dataList 添加的数量集合 * @param indexName indexName */ public void batchAddDocument(List<T> dataList, String indexName) { if (!this.existIndex(indexName)) { this.createIndex(indexName); } BulkRequest.Builder br = new BulkRequest.Builder(); dataList.forEach(data -> br.operations(op -> op .index(idx -> idx .index(indexName) .id(null) .document(data) )) ); try { BulkResponse result = elasticsearchClient.bulk(br.build()); if (result.errors()) { log.error("Bulk had errors"); for (BulkResponseItem item : result.items()) { if (item.error() != null) { log.error(item.error().reason()); } } } } catch (IOException e) { log.error("向es中添加document出错:{}",e.getMessage()); } } /** * 根据索引名称和字段查询数据. * * @param indexName 索引名称 * @param filedValue 查询字段值 * @param filedName 查询字段名称 */ public List<T> findDataList(String indexName, String filedName, String filedValue,Class<T> className) { try { SearchResponse<T> searchResponse = elasticsearchClient.search(s -> s.index(indexName) .query(q -> q .match(t -> t .field(filedName) .query(filedValue) ) ).query(q -> q .match(t -> t .field(filedName) .query(filedValue) ) ), className); List<Hit<T>> hitList = searchResponse.hits().hits(); List<T> dataList = new ArrayList<>(); for (Hit<T> mapHit : hitList) { dataList.add(mapHit.source()); } return dataList; } catch (IOException e) { log.error("【查询 -> 失败】从es中查询分析后的日志出错,错误信息为:{}", e.getMessage()); } return null; } }