因为我的电脑是windows,本篇主要还是讲windows环境搭建。搭建之前了解一下ELK是什么?
ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。
- ElasticSearch(简称ES)是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
- Logstash是一个完全开源的工具,可以对日志进行收集、分析、并将其存储供以后使用。
- kibana也是一个开源和免费的工具,他Kibana可以为Logstash和ES提供的日志分析友好的Web界面,可以帮助您汇总、分析和搜索重要数据日志。
下载地址:
https://www.elastic.co/cn/downloads/elasticsearch
https://www.elastic.co/cn/downloads/logstash
https://www.elastic.co/cn/downloads/kibana
此外,我们还需要一个用于管理Elasticsearch的web前端插件elasticsearch-head,源码地址:https://github.com/mobz/elasticsearch-head
1、基于MYSQL数据采集的ELK环境框架
Logstash同步采集Mysql数据,将数据存储到ES,Kibana负责数据查询展示。
2、elasticsearch安装
elasticsearch解压后,如果使用默认端口可以直接启动。
启动命令:D:softspringcloudelasticsearch-7.11.2inelasticsearch.bat
注:启动时遇到一个错误,X-Pack is not supported and Machine Learning is not available。
只需要在elasticsearch.yml文件里
添加一条配置即可:xpack.ml.enabled: false,再次启动成功。
在浏览器中输入:http://localhost:9200/,出现如下返回,说明ES安装成功。
3、elasticsearch-head安装
通过命令拉取elasticsearch-head代码:git clone git://github.com/mobz/elasticsearch-head.git
进入elasticsearch-head目录,执行npm install命令。
修改elasticsearch.yml,增加跨域的配置(需要重启es才能生效)
http.cors.enabled: true
http.cors.allow-origin: "*"
编辑elasticsearch-head/Gruntfile.js,修改服务器监听地址,connect节点增加hostname属性,将其值设置为*
connect: { server: { options: { hostname:'*', port: 9100, base: '.', keepalive: true } } }
编辑elasticsearch-head/_site/app.js, 修改默认es地址为http://localhost:9200/, 也可以不修改。
启动elasticsearch-head,运行命令:npm run start
浏览器打开:http://localhost:9100/
4、Logstash采集MYSQL数据环境搭建
4.1 配置
logstash解压后进入D:softspringcloudlogstash-7.11.2in目录,创建一个logstash.conf文件,文件内容如下:
因为我们要实现logstash读取mysql表数据,存储到ES。
input配置MYSQL的ip,用户名,密码。需要注意第10行,MYSQL连接驱动需要自己下载。
output需要配置ES服务器地址和端口:localhost:9200
1 input { 2 stdin {} 3 jdbc { 4 # mysql数据库连接 5 jdbc_connection_string => "jdbc:mysql://127.0.0.1:3306/apolloconfigdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC" 6 # mysqly用户名和密码 7 jdbc_user => "root" 8 jdbc_password => "111111" 9 # 驱动配置 10 jdbc_driver_library => "D:softspringcloudlogstash-7.11.2mysql-connector-javamysql-connector-java-8.0.15.jar" 11 # 驱动类名 12 jdbc_driver_class => "com.mysql.jdbc.Driver" 13 jdbc_paging_enabled => "true" 14 jdbc_page_size => "50000" 15 16 #执行的sql语句 17 statement => "SELECT * FROM es_search" 18 # 设置监听 各字段含义 分 时 天 月 年 ,默认全部为*代表含义:每分钟都更新 19 schedule => "* * * * *" 20 # 索引类型 21 #type => "blog" 22 } 23 } 24 25 output { 26 elasticsearch { 27 #es服务器 28 hosts => ["localhost:9200"] 29 #ES索引名称 30 index => "es_search" 31 #自增ID 32 document_id => "%{id}" 33 } 34 35 stdout { 36 codec => json_lines 37 } 38 }
4.2 启动
启动命令:logstash -f logstash.conf,通过-f指定启动的配置文件。
4.3 JDK安装目录问题
因为我的JDK安装目录为默认路径:C:Program Files (x86)Javajdk1.8.0_201,目录中有空格,启动logstash会报错,可以通过以下两种办法解决
将C:Program Files (x86)Javajdk1.8.0_201拷贝一份到D:softjdkjdk1.8.0_201,目标目录不能有空格,特殊字符
通过软链的方式,命令mklink。
以上两种方式选择一种即可,切记修改完目录后,再修改一下系统环境变量JAVA_HOME的VALUE指向。
4.4 logstash.conf配置错误
修改JDK后启动依然报错,提示logstash.conf文件第29行,第1列有特殊字符,因为文件内容从网上拷贝的,里面有空格,把空格去掉后可以通过命令logstash -f logstash.conf -t验证配置文件是否正确。见4.5!
4.5 配置文件验证
执行logstash -f logstash.conf -t后,如果最后显示Configuration OK就说明文件内容没有问题了。
5、kibana安装
解压后修改config/kibana.yml文件
server.port: 5601 server.host: "localhost" elasticsearch.hosts: ["http://localhost:9200"]
启动:D:softspringcloudkibana-7.11.2inkibana.bat
浏览器输入:http://localhost:5601/,看到下面页面说明启动成功了。
另外kibana支持中文,在kibana.yml文件末尾增加如下配置,重启kibana,UI就是中文的了。
# Supported languages are the following: English - en , by default , Chinese - zh-CN . i18n.locale: "zh-CN"
中文页面展示:
6、ELK环境验证
环境准备好,手动往es_search插入几条数据。
观察logstash日志输入,可以看到logstash已经采集到了Mysql数据表的数据。
[2021-03-25T17:05:00,361][INFO ][logstash.inputs.jdbc ][main][f169fd82333ea4317b94025483cdf2d344c56bd4c2e83177f677724d52b4b416] (0.001105s) SELECT * FROM (SELECT * FROM es_search) AS `t1` LIMIT 50000 OFFSET 0 {"name":"ab","@version":"1","createtime":"2021-03-17T18:22:52.000Z","@timestamp":"2021-03-25T09:05:00.367Z","id":1,"content":"dsdsf"} {"name":"Leo","@version":"1","createtime":"2021-03-18T11:42:51.000Z","@timestamp":"2021-03-25T09:05:00.367Z","id":2,"content":"hello"} {"name":"张三","@version":"1","createtime":"2021-03-18T14:04:06.000Z","@timestamp":"2021-03-25T09:05:00.368Z","id":3,"content":"吃饭"}
从elasticsearch-head查看数据,搜索条件选择es_search,点击搜索按钮。
从kibana查看数据
通过ES接口查询,源码见x-demo-elasticsearch-api模块(PS:源码已上传Github, 欢迎指教。https://github.com/shileishmily/spring-cloud-x.git)
build.gradle依赖
dependencies { compile("org.elasticsearch:elasticsearch:7.11.2") compile("org.elasticsearch.client:elasticsearch-rest-high-level-client:7.11.2") }
创建一个查询controller
package com.x.demo.es.controller; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpHost; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.ScoreSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.Map; /** * @author Leo */ @RestController @RequestMapping("es/demo") @Slf4j public class EsDemoController { @GetMapping("query") public String query() throws IOException { String hostName = "localhost"; int port = 9200; String indexName = "es_search"; //创建Client RestHighLevelClient restHighLevelClient = new RestHighLevelClient( RestClient.builder(new HttpHost(hostName, port, "http")) ); //构建匹配条件 QueryBuilder queryBuilderAll = QueryBuilders.matchAllQuery(); //组合匹配条件 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(queryBuilderAll); //创建查询 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.fetchSource(new String[]{"id", "name", "content"}, null); sourceBuilder.query(boolQueryBuilder); sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.DESC)); //创建搜索Request SearchRequest request = new SearchRequest(indexName); request.searchType("dfs_query_then_fetch"); request.source(sourceBuilder); //解析反馈结果 SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); for (SearchHit hit : hits) { Map tempSource = hit.getSourceAsMap(); log.info(tempSource.toString()); } return "success"; } }
通过浏览器调用接口:http://localhost:9400/es/demo/query
观察控制台日志输出:
2021-03-25 17:54:57.093 WARN 70704 --- [nio-9400-exec-4] org.elasticsearch.client.RestClient : request [POST http://localhost:9200/es_search/_search?typed_keys=true&max_concurrent_shard_requests=5&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=dfs_query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true] returned 1 warnings: [299 Elasticsearch-7.11.2-3e5a16cfec50876d20ea77b075070932c6464c7d "Loading the fielddata on the _id field is deprecated and will be removed in future versions. If you require sorting or aggregating on this field you should also include the id in the body of your documents, and map this field as a keyword field that has [doc_values] enabled"] 2021-03-25 17:54:57.094 INFO 70704 --- [nio-9400-exec-4] c.x.demo.es.controller.EsDemoController : {name=张三, id=3, content=吃饭} 2021-03-25 17:54:57.094 INFO 70704 --- [nio-9400-exec-4] c.x.demo.es.controller.EsDemoController : {name=Leo, id=2, content=hello} 2021-03-25 17:54:57.094 INFO 70704 --- [nio-9400-exec-4] c.x.demo.es.controller.EsDemoController : {name=ab, id=1, content=dsdsf}
可以看到通过ES接口也可以查询到数据了。
结束!