日志收集工具ELK,简单集群配置

因项目部署在多台服务器上,如果出现Bug需要查询日志的时候,日志非常难查询。所以采用Logstash来收集日志,通过Kibana页面将日志展示出来。一开始偷懒,使用Docker安装了个单机版的ELK,后面日志体量上来后,发现只要增加条件查询,ELK就贼容易崩溃!

1657073430543.jpg

后面通过排查发现,增加条件检索后ElasticSearch性能降的很快,内存消耗大大增加。之前通过Docker安装ELK只是简单玩玩,索引也只根据日期创建了个索引,加上一开始CPU、内存分配都很小,搜索量上来后,ES崩溃也就很正常了! 回归正题,此次更新ELK环境,准备了三台服务器,准备将ES部署为集群模式,一台Mester,两台Node Data,然后将Kibana、Logstash安装在Mester机器上。部署方式采用二进制部署方式,版本为8.2.3,官网也支持K8s和Docker部署。

ES

前置配置

  • 创建文件夹(在home下面创建elk文件夹,方便查找安装包及解压文件)

    # 创建目录
    mkdir elk
    # 这里本该为新用户赋予目录权限,我为了省事,直接把该目录下权限放开给所有用户这个可以自行考虑
    chmod -R 777 elk
    
  • 创建用户,并设置初始密码(基于安全考虑,es默认不让root用户启动)

    # 创建用户,将你自己的用户名替换’用户名‘,用户名是不需要引号包裹的
    useradd ’用户名‘
    # 设置密码,执行后会让输入密码,并二次确认,确认成功后即设置成功,可以用新用户登陆服务器
    passwd '用户名'
    
  • 调整进程最大打开文件数量

    vim /etc/security/limits.conf 
    # 直接末尾添加限制 
    es soft nofile 65536 
    es hard nofile 65536
    
  • 调整进程最大虚拟内存区域数量及关闭防火墙

    echo vm.max_map_count=262144>> /etc/sysctl.conf
    sysctl -p
    # 关闭防火墙
    systemctl stop firewalld
    # 设置重启后防火墙布重启
    systemctl disable firewalld
    
  • 添加服务器名解析,此处将你自己ip替换成【’服务器1ip‘】即可

    cat > /etc/hosts << EOF 
    '服务器1ip' es-node-01 
    '服务器2ip' es-node-02 
    '服务器3ip' es-node-03
    EOF
    
  • 安装配置ES

在配置ES前,得先切换前面创建好的用户进去/home/elk目录下,创建es/data,es/logs目录,用于保存数据及保存日志。ES的集群名称配置一样es-cluster,三台ES节点的node.name分别为 es-node-01、es-node-02、es-node-03,network.host配置为各自本机的IP地址。

cd /home/elk
# 下载Es压缩包
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.2.3-linux-x86_64.tar.gz
# 三台服务器都准备好安装包,进行解压
tar -xvf elasticsearch-8.2.3-linux-x86_64.tar.gz
cd elasticsearch-8.2.3
# 编写配置文件
vi config/elasticsearch.yml
# 以下为配置信息,按照各自的数据替换
cluster.name: es-cluster
node.name: es-node-01
node.attr.rack: r1
path.data: /home/elk/es/data
path.logs: /home/elk/es/logs
network.host: ‘服务器ip’
discovery.seed_hosts: ["ip1", "ip2", "ip3"]
cluster.initial_master_nodes: ["ip1", "ip2", "ip3"]
xpack.security.enabled: false
xpack.security.transport.ssl.enabled: false
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,X-Requested-With,Content-Type,Content-Length
  • 启动ES服务

    # 依次启动三台服务器的ES服务 
    ./bin/elasticsearch -d
    

访问3台服务器9200端口,如果都看到如下信息则代表ES启动成功
在这里插入图片描述
再次查看集群的健康状态, http://10.17.16.30:9200/_cat/health
在这里插入图片描述
上图具体含义可点击跳转其他文章查看

遇到的问题及解决方案

到这,可以说已经是已经成功安装好了ES,但是安装过程中还是遇到了一些问题,在此简单说下问题和解决方法

  • main ERROR RollingFileManager,具体报错信息如下

    2022-07-05 10:22:07,358 main ERROR RollingFileManager (/home/elk/elasticsearch-8.2.3/logs/elasticsearch_server.json) java.io.FileNotFoundException: /home/elk/elasticsearch-8.2.3/logs/elasticsearch_server.json (Permission denied) java.io.FileNotFoundException: /home/elk/elasticsearch-8.2.3/logs/elasticsearch_server.json (Permission denied)
      at java.io.FileOutputStream.open0(Native Method)
      at java.io.FileOutputStream.open(FileOutputStream.java:270)
      at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
      at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:746)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:716)
      at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:114)
      at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:100)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:217)
      at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:146)
      at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:62)
      at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1120)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1045)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1037)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:651)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:247)
      at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:293)
      at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:626)
      at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:302)
      at org.elasticsearch.common.logging.LogConfigurator.configure(LogConfigurator.java:222)
      at org.elasticsearch.common.logging.LogConfigurator.configure(LogConfigurator.java:118)
      at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:369)
      at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:166)
      at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:157)
      at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:77)
      at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:112)
      at org.elasticsearch.cli.Command.main(Command.java:77)
      at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsear:ch.java:122)
      at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:80)
    

这些错误都是因为之前的Permission denied引起的。
这是因为当前启用用户没有权限写入这些文件。切换到root用户重新赋权限就OK了。但是按照我前面将整个elk目录都放开的话,这个问题应该不会出现了

  • Exception in thread “main“ org.elasticsearch.bootstrap.BootstrapException:… 具体错误信息如下

    Exception in thread “main“ org.elasticsearch.bootstrap.BootstrapException:java.nio.file.AccessDeniedException:/home/elk/elasticsearch-8.2.3/config/elasticsearch.keystore Likely root casue:java.nio.file.AccessDeniedException:/home/elk/elasticsearch-8.2.3/config/elasticsearch.keystore
      at sun.nio.fs.UnixExcption.translateToIOException(UnixException.java:84)
      at sun.nio.fs.UnixExcption.rethrowAsIOException(UnixException.java:102)
      at sun.nio.fs.UnixExcption.rethrowAsIOException(UnixException.java:107)
      at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
      at java.nio.file.Files.newByteChannel(Files.java:361)
      at java.nio.file.Files.newByteChannel(Files.java:407)
    

根据报错信息提示,是elasticsearch.keystore文件的权限问题,我们进入该文件所属目录查看文件权限,果不其然,这个文件权限属于root,不是新建用户的权限,解决方法是直接删除elasticsearch.keystore,切换回新用户启动es后该文件会自动创建。这个问题是使用root用户启动的延续问题。

目前我遇到的,大多是没切换用户导致的一系列权限问题,运气比较好,其他问题倒是也出现。

kibana安装

kibana的版本要与ES的版本保持一致,如果没保持一致会出现kibana连接不上ES等问题,使用新用户登陆服务器并进入/home/elk目录下

# kibana下载
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.2.3-linux-x86_64.tar.gz
# 解压文件
tar -xvf kibana-8.2.3-linux-x86_64.tar.gz
# 进入解压目录
cd kibana-8.2.3
# 修改配置
vim config/kibana.yml
# 配置信息
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://‘ES服务器ip’:9200/"]
i18n.locale: "zh-CN"
# 启动kibana服务,如需后台启动,前面加nuhup,尾部加&
nohup ./bin/kibana > logs/kibana.log 2>&1 &

启动后访问5601端口,如出现下图页面则启动成功

在这里插入图片描述

Logstash

日志收集除了Logstash之外,还可以选择Filebeat,区别在于Logstash是通过jvm写的,功能比较多,具有filter功能,能过滤日志,资源消耗比较大;Filebeat是golang写的,比较轻量级,占用资源更少;Logstash是同步收集日志上报,Filebeat是收集日志后通过消息队列再通过logstash去获取。这里是直接使用Logstash

# 下载压缩包
wget https://artifacts.elastic.co/downloads/logstash/logstash-8.2.0-linux-x86_64.tar.gz
# 解压
tar -xvf logstash-8.2.0-linux-x86_64.tar.gz
# 修改配置文件
cd logstash-8.2.0
vim config/logstash.conf
# 配置信息
input {
     tcp {
         port => 5044
     }
}
output {
     elasticsearch {
         hosts => ["http://ip1:9200","http://ip2:9200","http://ip3:9200"]
         index => "%{app_id}"
     }
}
# 检查配置文件语法是否正确
bin/logstash -f config/logstash.conf --config.test_and_exit
# 启动服务,如需后台启动,前面加nohup,尾部加&
nohup bin/logstash -f config/logstash.conf --config.reload.automatic &

到这,ELK环境配置基本就结束了,剩下来就是将ELK集成进项目中,实现日志收集上报,然后通过页面可以查看到上报的日志。

SpringBoot集成

项目中引入依赖

<dependency>
   <groupId>net.logstash.logback</groupId>
   <artifactId>logstash-logback-encoder</artifactId>
   <version>5.2</version>
</dependency>

日志配置文件

<appender name="logstash"
          class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>‘上报地址’</destination>
    <!-- 日志输出编码 -->
    <encoder charset="UTF-8"
            class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{‘额外参数,用于区分服务器或端’}</customFields>
        <providers>
            <timestamp>
                <timeZone>UTC</timeZone>
            </timestamp>
            <pattern>
                <pattern>
                    {
                    "severity": "%level",
                    "service": "${springAppName:-}",
                    "trace": "%X{X-B3-TraceId:-}",
                    "span": "%X{X-B3-SpanId:-}",
                    "exportable": "%X{X-Span-Export:-}",
                    "pid": "${PID:-}",
                    "thread": "%thread",
                    "class": "%logger{40}",
                    "rest": "%message"
                    }
                </pattern>
            </pattern>
        </providers>
    </encoder>
</appender>

问题记录

1、安装成功后无任何报错,缺无法上报日志信息

在我将ELK配置完成并集成进项目中后,我发现日志无法收集,一开始认为是kibana没有连接上ES,但是我打开页面一切显示正常,后面发现是在Logstash配置文件中,imput下使用的beats而不是tcp,beats我猜可能是给Filebeat模式使用,具体未继续深究。

2、配置文件中定义了自定义字段,在页面也无法获取

如上述日志配置文件中,在customFields标签中定了appName的自定义字段,然后到kibana页面中,无论重新自定义字段或者读取日志都没办法获取到该属性,更别说通过该数据检索数据了,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bLmJrVaj-1668839752713)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c4ab7b8eb16b46f5901c74878218afe2~tplv-k3u1fbpfcp-watermark.image?)]
后通过查看资料和对比之前通过docker中logstash的配置文件发现在input中可以指定输出类型,不指定的话默认是字符串,所以才没办法读取到自定义字段,json-lines是根据每行的日志输入为json;还有一个属性是json,应该是整个输出为json,这个没去使用,具体就不太清楚了。

input {
  tcp {
    port => 5044
    codec => json_lines
  }
}

3、每次启动、停止服务太麻烦

发现不管是ES也好还是Kibana、Logtash也好,通过bin目录下启动还算可以,但是要停止服务,就得自己通过ps -ef去查询进程了,然后杀死进程,难道就没有一个简单点的方式吗?别说,还真有,如下,在bin的上层目录建立两个sh脚本文件,一个里面存放启动命令;一个存放服务停止命令。以Logstash的停止命令为例,如下:

pid=`ps -ef | grep logstash | grep -v grep | awk '{print $2}'`
if [ -n "${pid}" ];then
    echo "Will shutdown logstash: ${pid}"
    kill -9 ${pid}
fi

这样就可以通过执行sh文件来停止服务了,是不是简单多了!

4、ES启动后,发现内存资源消耗大

初始服务器的内存分配是4G,启动ES后发现内存消耗达到了50%,峰值甚至到了70%多,在FinalShell(Mac远程连接服务器工具,好用,推介)中发现后猜测是不是内存分配的太小了,于是乎将内存加大至8G,心想这问题应该是解决了吧。哦吼,就算内存加大了一倍,ES启动后内存消耗的比例丝毫没降,一个java的进程(ES的进程)消耗了4.4G的内存,算了先用着,有问题或者有时间再去研究研究

参考文章:https://blog.csdn.net/www_xuhss_com/article/details/125494770

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值