es + logstash + kibana实现分布式集群
最近因为公司技术需要,需要收集日志采集,因此搭建了一套分布式的ELK集群,从零开始搭建一套简单的高可用案例,废话不多说,开始准备
该架构基于springboot 2.x版本,使用的es + logstash + kibana需要三者的版本一致!一致!一致!!下载包的时候一定要注意版本一致,不然会浪费很多时间,本文统一使用7.5.1,需要的可以去百度云去下载
版本链接: https://pan.baidu.com/s/1hY0-_ZkhE733_j4ZM7NSmQ 提取码: aai6 复制这段内容后打开百度网盘手机App,操作更方便哦
1.搭建es集群
为什么一开始就搞集群?因为单节点和集群搭建过程都是一样的,而且在今后开发中集群的占比更大,高可用,何乐而不为呢?
将压缩包解出3份,分为3个节点,可用下面命令进行解压缩和复制。
tar -zxvf elasticsearch-7.5.1-linux-x86_64.tar.gz elasticsearch-7.5.1-node1
cp elasticsearch-7.5.1-node1 elasticsearch-7.5.1-node2
cp elasticsearch-7.5.1-node1 elasticsearch-7.5.1-node3
为什么是3个节点?因为2个节点可能会出现脑裂。
那又为什么会脑裂?脑裂就是当前master节点假死状态,slave节点晋升为master,此时上任master又活了过来,造成集群中存在两个master节点,但是master节点负责写数据,那两个master谁负责?所以数据就混乱了(大致这个意思,当节点之间网络传输出现问题,相互不能访问,也是脑裂)
首先进入第一个节点的conf文件夹,编辑elasticsearch.yml文件,添加一下配置
# 集群名称
cluster.name: shaun-es
# 节点名称
node.name: node-1
# 主节点
node.master: true
# 数据节点
node.data: true
# 确保外网和内网均能访问
network.host: 0.0.0.0
# http协议,用户外部通讯
http.port: 9200
# Tcp协议,用于节点间的数据传输
transport.port: 9300
# 最大节点数量
node.max_local_storage_nodes: 3
#三个节点
discovery.seed_hosts: ["172.17.0.8:9300", "172.17.0.8:9301", "172.17.0.8:9302"]
# 确保当前节点是主节点
cluster.initial_master_nodes: ["node-1"]
http.cors.enabled: true
http.cors.allow-origin: "*"
进入第二个节点的conf文件夹,编辑elasticsearch.yml文件,添加一下配置
cluster.name: shaun-es
node.name: node-2
node.master: false
node.data: true
network.host: 0.0.0.0
http.port: 9201
transport.port: 9301
node.max_local_storage_nodes: 3
discovery.seed_hosts: ["172.17.0.8:9300", "172.17.0.8:9301","172.17.0.8:9302"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
http.cors.enabled: true
http.cors.allow-origin: "*"
进入第三个节点的conf文件夹,编辑elasticsearch.yml文件,添加一下配置
cluster.name: shaun-es
node.name: node-3
node.master: false
node.data: true
network.host: 0.0.0.0
http.port: 9202
transport.port: 9302
discovery.seed_hosts: ["172.17.0.8:9300", "172.17.0.8:9301","172.17.0.8:9302"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
http.cors.enabled: true
http.cors.allow-origin: "*"
然后配置就ok了,然后开放服务器对应的端口
现在创建一个维护ES对应的用户,使用该用户开启动es服务
ES默认禁止使用root用户对es维护,如果非得想root用户的话,启动的时候加上 -allow-root 参数
不过还是建议遵循es的建议,创建一个子用户来启动es
然后依次进入每个节点的bin目录,启动es
./elasticsearch -d
记得加上-d参数,后台运行
现在一个简单的es集群就部署好了,可通过ps命令查看es的进程
ps -ef | grep elasticsearch
启动可能会遇到的坑
1、max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
每个进程最大同时打开文件数太小,可通过下面2个命令查看当前数量
ulimit -Hn
ulimit -Sn
修改/etc/security/limits.conf文件,增加配置,用户退出后重新登录生效
* soft nofile 65536
* hard nofile 65536
2、max number of threads [3818] for user [es] is too low, increase to at least [4096]
问题同上,最大线程个数太低。修改配置文件/etc/security/limits.conf(和问题1是一个文件),增加配置
* soft nproc 4096
* hard nproc 4096
ulimit -Hu
ulimit -Su
3、max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
修改/etc/sysctl.conf文件,
vi /etc/sysctl.conf
#增加配置
vm.max_map_count=262144
执行命令sysctl -p生效
4、Exception in thread "main" java.nio.file.AccessDeniedException: /usr/local/elasticsearch/elasticsearch-6.2.2-1/config/jvm.options
elasticsearch用户没有该文件夹的权限,执行命令
#添加用户
useradd -m es
#创建授权目录
chown -R es:es /usr/local/elasticsearch/
2.项目引入
es部署好,那就服务添加下面pom依赖,咱先使用springboot封装的,简单明了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置文件application.yml,使用集群模式连接es,注意集群名称,需要和每个节点的统一对应
spring:
data:
elasticsearch:
cluster-nodes: ip:9300,ip:9301,ip:9302
cluster-name: shaun-es
二、logstash
1.安装
还是一样,下载logstash包,官网有,确定7.5.1版本
然后解压,修改配置
tar -zxvf logstash-7.5.1.tar.gz
编辑logstash.conf,添加以下配置,该配置通过logstash不仅存储了项目运行日志,同时还将mysql和elasticsearch的日志一起插入到es中
编辑conf目录中logstash.conf或者logstash-simple.conf文件
# 输入我这定义来两种方式,一种是tcp,另一种是file文件
# 第一个tcp是将项目日志通过4560端口数据
# 其他的则是指定的日志文件
input {
tcp{
port=>4560
type=>"elk"
codec=>json_lines
}
file{
path=>"/home/es/testdemo"
type=>"demo"
start_position=>"beginning"
}
file{
path=>"/var/log/mysqld.log"
type=>"mysql"
start_position=>"beginning"
}
file{
path=>"/home/es/elasticsearch-node1/logs/shaun-es.log"
type=>"elastic"
start_position=>"beginning"
}
}
# 这里通过input中定义的type来匹配,指定索引名称和格式
output {
if[type] == "elk"{
elasticsearch{
hosts=>["127.0.0.1:9200"]
index=>"elk-%{+yyyy.MM.dd}"
}
}
if[type] =="elastic"{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "elastic-%{+YYY.MM.dd}"
}
}
if[type] =="mysql"{
elasticsearch{
hosts=>["127.0.0.1:9200"]
index=>"mysql-%{+yyyy.MM.dd}"
}
}
if[type] =="demo"{
elasticsearch{
hosts=>["127.0.0.1:9200"]
index=>"test-%{+yyyy.MM.dd}"
}
}
}
启动logstash
../bin/logstash -f logstash-sample.conf --config.reload.automatic
//指定logstash.conf文件,启动logstash,后面跟自动reload配置,可以不加该参数
2.1项目集成springboot+logstash 配置.
引入pom依赖
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.1</version>
</dependency>
添加logback.xml文件,项目使用的是springboot默认的日志系统,logback,在logback.xml中添加配置
<configuration>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 这里指定logstash部署服务器的地址和端口 -->
<destination>ip:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<root level="INFO">
<appender-ref ref="LOGSTASH" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
然后就ok了啊,这时候启动项目,输出的日志就会通过logback.xml配置指向的logstash服务存储到es中,日志的存储过程已经实现了,现在把日志内容显示出来就完成了
2.2项目集成springboot+log4j 配置
引入pom
<dependency>
<groupId>biz.paluch.logging</groupId>
<artifactId>logstash-gelf</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
</appenders>
<Socket name="logstash" host="172.17.125.76" port="4560" protocol="TCP">
<PatternLayout pattern="${LOG_PATTERN}" />
<!--<JsonLayout properties="true"/>-->
</Socket>
</appenders>
<loggers>
<AsyncLogger name="com.glodon" level="debug" includeLocation="false" >
<!--<appender-ref ref="Console"/>-->
<appender-ref ref="logstash" />
</AsyncLogger>
</loggers>
三、kibana
解压,修改conf文件中kibana.yml文件
tar -zxvf kibana-7.5.1-linux-x86_64.tar.gz
server.port: 5601 #默认端口 server.host: "0.0.0.0" #可通过外网访问,默认只支持localhost, elasticsearch.hosts: ["http://ip:9200","http://ip:9201","http://ip:9202"] #指定es集群,这里只指向一个节点也ok
最后一步, 使用nohup后台启动
这里同样不建议使用root用户来启动,非要使用root,加上-allow-root参数
nohup ./kibana &
成功后效果