全文检索
全文检索将采用Elasticsearch(简称ES)组件提供检索服务,这里只介绍单节点的安装、配置与使用。
1、Rancher安装ES
这里采用elasticsearch-ik:7.17.6 镜像版本进行安装,该版本已经基于官方的基础镜像并整合了中文分词IK插件。
1.1、创建ConfigMap
先以ConfigMap的方式创建ES的配置文件elasticsearch.yml,用于挂载到ES的配置文件
如果启用安全后xpack.security.enabled设置为true,如不需要用户密码验证,给配置为false,
# elasticsearch.yml文件内容
cluster.name: "dmm-es-cluster"
network.host: 0.0.0.0
node.data: true
node.master: true
discovery.type: single-node
ingest.geoip.downloader.enabled: false
xpack.security.enabled: true
xpack.license.self_generated.type: basic
xpack.security.transport.ssl.enabled: true

1.2、部署应用
- 配置镜像、端口
名称: elasticsearch-server (同时作为服务名)
Docker镜像 :172.16.102.2:5000/library/elasticsearch-ik:7.17.6
端口映射:9200(http端口)、9300(tcp端口)

- 挂载配置文件
卷名:elasticsearch-config
默认模式 :650
容器路径 :/usr/share/elasticsearch/config/elasticsearch.yml
子路径 :elasticsearch.yml

- 添加PVC
容量:xx GiB (根据实现需要申请容量)
容器路径 :/usr/share/elasticsearch/data


- 初始化密码
启用认证后,需要进行pod里进行密码初始化
#启用安全认证后,在应用部署后,到pod中执行命令,交互式设置密码(es、kibana、logstash等)
cd /usr/share/elasticsearch/bin
./elasticsearch-setup-passwords interactive

访问nodeport暴露的端口:http://172.16.103.10:20012/ ,输入用户密码:elastic/xxx (xxx为上面初始化设置的密码),正常显示如下信息,就表示ES已经配置成功了。

2、Rancher安装Kibana
Kibana用于对ES的数据进行可视化管理,镜像版本保持跟ES一致。
2.1、创建ConfigMap
指定ES的host,这里可以使用服务名进行配置,elasticsearch.password密码为ES中初始化设置的密码
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch-server:9200" ]
elasticsearch.username: elastic
elasticsearch.password: ******

2.2、部署应用
名称: kibana-ui (可自定义名称)
Docker镜像 :172.16.102.2:5000/library/kibana:7.17.6
端口映射:5601
环境变量:
I18N_LOCALE:zh-CN (指定默认语言)
SERVER_HOST:0.0.0.0

- 配置数据卷
名称:kibana-vol
默认模式 :644
容器路径:/usr/share/kibana/config/kibana.yml
子路径:kibana.yml

启动后通过暴露的Nodeport端口进行访问,在启用安全后,需要输入用户密码进行访问:http://172.16.103.10:31605/

3、应用开发
应用中使用有很多种方式,ES提供很多种客户端的访问方式Transport client、Rest client、Java Client,在7.17版本时Rest client也已经被 deprecated弃用,推荐使用Java Client,包括现在最新版本的8.x。
系统框架目前仍采用的是RestHighLevelClient客户端进行连接,下面的示例也以此为主。
3.1、添加Maven依赖
<properties>
<elasticsearch.version>7.14.2</elasticsearch.version>
</properties>
<!-- elasticsearch-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
3.2、添加配置
该配置可以自定义属性,主要用于初始化RestClientConfig
waf:
elasticsearch:
# 多个IP以逗号分隔
hosts: ${ES_HOSTS:elasticsearch-server}
port: ${ES_PORT:9200}
scheme: ${ES_SCHEME:http}
username: ${ES_USERNAME:elastic}
password: ${ES_PASSWORD:wiseda@2020}
thread-count: ${ES_THREAD_COUNT:20}
no-match-size: ${ES_NO_MATCH_SIZE:300}
num-of-fragment: ${ES_NUM_OF_FRAGMENT:6}
fragment-size: ${ES_FRAGMENT_SIZE:50}
3.3、配置Config
该ES config主要是针对于http的方式,如果启用的是https,可以自行修改,进行https认证。
@Configuration
@Slf4j
public class ElasticsearchRestClientConfig {
@Value("${waf.elasticsearch.hosts}")
String[] hostAddress;
@Value("${waf.elasticsearch.port}")
int port;
@Value("${waf.elasticsearch.scheme}")
String scheme;
@Value("${waf.elasticsearch.username}")
String username;
@Value("${waf.elasticsearch.password}")
String password;
@Value("${waf.elasticsearch.thread-count:10}")
int threadCount;
@Bean
public RestClientBuilder restClientBuilder() {
Assert.notNull(hostAddress,"ES服务地址未正常配置");
HttpHost[] hosts = Arrays.stream(hostAddress).map(this::makeHttpHost).toArray(HttpHost[]::new);
log.info("scheme:{}, es hosts:{}",scheme,Arrays.toString(hosts));
return RestClient.builder(hosts);
}
@Bean(name = "highLevelClient")
public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
// 默认http认证
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(username,password));
// 认证和线程数
restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> {
// 认证
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
httpClientBuilder.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(threadCount).build());
return httpClientBuilder;
});
// 超时超时设置
restClientBuilder.setRequestConfigCallback(requestConfigCallback -> {
requestConfigCallback.setConnectTimeout(1000);
requestConfigCallback.setSocketTimeout(10000);
return requestConfigCallback;
});
return new RestHighLevelClient(restClientBuilder);
}
private HttpHost makeHttpHost(String host) {
return new HttpHost(host,port,scheme);
}
}
3.4 基本使用
基于RestHighLevelClient的使用可以自行搜索。
private final RestHighLevelClient highLevelClient;
// 创建索引
public void createIndex() throws IOException {
CreateIndexRequest index = new CreateIndexRequest(INDEX_NAME);
XContentBuilder builder = JsonXContent.contentBuilder();
builder.startObject().startObject("mappings").field("properties",ESProperties.getProperties()).endObject().startObject("settings").field("number_of_shards",3).field("number_of_replicas",1).endObject().endObject();
index.source(builder);
CreateIndexResponse response = highLevelClient.indices().create(index,RequestOptions.DEFAULT);
log.debug("{}-索引是否创建成功:{}",response.index(),response.isAcknowledged());
}
// 向索引里添加文档
public Map saveDocIndex(ESDocModel es) throws Exception {
IndexRequest request = new IndexRequest();
es.setName(JsXssFilter.xxsClear(es.getName()));
es.setRemark(JsXssFilter.xxsClear(es.getRemark()));
String json = objectMapper.writeValueAsString(es);
request.index(INDEX_NAME).id(es.getId()).source(json,XContentType.JSON);
IndexResponse response = highLevelClient.index(request,RequestOptions.DEFAULT);
Map retMap = new HashMap(1);
retMap.put("id",response.getId());
return retMap;
}
}
参考资料
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-overview.html
