微服务日志系统

1. 初始ELK
    ELK是一个技术栈,包括Elasticsearch、Logstash和Kibana,ELK是三种技术首字母的缩写。ELK主要用于日志收集、存储和查询。
    1.1 为什么要用ELK
        ELK主要用于处理日志。作用如下:
        a) 定位问题:线下也许可以通过debug一行一行来调试,但是线上可能不会给你远程调试的权限;当然,如果代码庞大,调试可能也是很费劲的。通常我们通过打印一些error级别的日志(尤其是在 try-catch的catch块中,将堆栈信息打印出来)来定位一些问题。
        b) 分析性能:在调用一个方法时,我们想分析一下该方法的性能怎么办?可以这样做,在方法开始执行时记录一个开始时间,在方法结束时使用info级别的日志记录结束时间与之前的开始时间的差值,通过这样的记录,可以看出该方法执行时间的长度,进而判断该方法是否是性能瓶颈,决定是否需要优化该方法。
        c) 数据挖掘:做数据挖掘需要大量的有价值的数据。比如我们要制定一个广告投放策略,想为不同的用户投放不同的广告,这就需要为用户打一些标签,尤其是兴趣标签。打标签就可以通过分析日志来实现(当然,埋点也可以)。
    日志很重要,但是人工分析日志可能不是一件容易的事。假设一个服务只部署在一台机器上,我们分析一份日志就好了,但是如果这个服务被部署在6台机器上,那么就需要分析6份日志,那就不好办了。这个时候该ELK出场了!使用Logstash将日志收集在一起,使用Elasticsearch将日志存储起来并提供搜索接口,使用Kibana进行日志的查询并展示。非常简单的解决了多机器多分日志的问题。当然,分工分析日志的难点不只这一个,比如还有日志格式不统一等问题,这些都可以通过ELK来解决。
    1.2 ELK常用的两种架构
    ELK最常用的两种架构为最简架构和缓存架构。
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MjU1Mzg0,size_16,color_FFFFFF,t_70
    最简架构就是使用logstash收集日志,之后将日志直接存储到Elasticsearch中,最后用户通过Kibana查询日志并展示。在并发日志量比较小的情况下,使用该架构是没问题的。但是随着并发日志量的增加,由于Logstash将数据索引到Elasicsearch比较慢,如果索引失败,数据还会丢失,因此有了ELK的第二种架构,该架构也是企业中最常用的架构:缓存架构。
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MjU1Mzg0,size_16,color_FFFFFF,t_70
    很明显,缓存架构要比最简架构复杂。实际上相较于最简架构,缓存架构只做了两件事。第一,将原本的Logstash按职能分为了Logstash-Shipper(简称Shipper)和Logstash-Indexer(简称Indexer),其中Shipper用于收集日志,Indexer用于指定索引;第二,在Shipper和Indexer之间添加了Redis来做缓存,减小Indexer将数据索引到Elasticsearch的压力。
    现在的流程是这样的:Shipper进行日志收集,之后传到Redis中,Redis再将数据弹出给Indexer,Indexer将数据索引到Elasticsearch,最后用户使用Kibana查询日志。
    流程依旧很简单,但是笔者在这里给出的架构图包含更多的信息,我们来看一下流程:
    1,假设有三个服务,其中myserviceA和myserviceB的日志会以tcp协议发到Shipper的4560端口,而myserviceC会发到4561端口。
    2,4560的Shipper将数据发到Redis的    queue1队列中,4561的Shipper发到queue2队列。
    3,queue1队列中的数据弹到图中上边的Indexer中,并指定索引名为"myindex1-%{+YYYY.MM.dd}",queue2队列中的数据弹到图中下边的indexer中,并指定索引名为"myindex2-%{+YYYY.MM.dd}".
    4,queue1队列中的数据弹到图中上边的Indexer中,并指定索引名为"myindex1-%{+YYYY.MM.dd}",queue2队列中的数据弹到图中下边的Indexer中,并指定索引名为"myindex2-%{+YYYY.MM.dd}"。
    5,在Kibana中选定不同的索引来分别查看三个服务的日志。
2. 搭建ELK系统
    安装环境及软件版本如下:
        系统,centos7;ip是10.211.55.4
        Redis,3.2.6
        Elasticsearch,2.4.0
        Logstash,2.4.0
        Kibana,4.6.1
    注:ELK三个软件的版本是需要匹配的,如果不知道怎么匹配,就全选最新的版本,这样是没问题的。4
    2.1 安装配置启动Redis
    第一步,在开发机下载redis-3.2.6.tar.gz,下载地址为:https://redis.io/。
    第二步,将在开发机下载好的redis-3.2.6.tar.gz复制到10.211.55.4。
    scp redis-3.2.6.tar.gz root@10.211.55.4:/opt/
    第三步,解压安装。
    cd /opt/
    tar -zxf redis-3.2.6.tar.gz
    cd redis-3.2.6/
    make && make install
    第四步,修改配置文件
    vi /opt/redis-3.2.6/redis.conf
    修改如下配置:
    bind 10.211.55.4
    第五步,启动redis-server。
    redis-server /opt/redis-3.2.5/redis.conf
    最后,通过rdm连接或redis-cli操作试试是否启动成功。
    2.2 安装配置启动Elasticsearch
    第一步,在开发机下载elasticsearch-2.4.0.tar.gz,下载地址为:https://www.elastic.co/downloads。
    第二步,将在开发机下载好的elasticsearch-2.4.0.tar.gz复制到10.211.55.4。
    scp elasticsearch-2.4.0.tar.gz root@10.211.55.4:/opt/
    第三步,解压安装。
    cd /opt/
    tar -zxf elasticsearch-2.4.0.tar.gz
    第四步,修改配置文件。
    vi /opt/elasticsearch-2.4.0/config/elasticsearch.yml
    修改如下配置:
    cluster.name:mymicroservice-elk
    node.name:node-es-1
    path.data:/data/es/data
    path.logs:/data/es/logs
    network.host:10.211.55.4
    http.port:9200
    这里,指定了该Elasticsearch节点所属的集群、节点的名称、数据文件存储的位置、日志文件存储的位置,以及该节点绑定的host和port。
    第五步,启动Elasticsearch。
    sudo chown -R xiaoming:xiaoming /opt/elasticsearch-2.4.0/
    sudo chown -R xiaoming:xiaoming /data/es/
    nohup /opt/elasticsearch-2.4.0/bin/elasticsearch &
    注意,Elasticsearch不允许以root用户来启动服务,所以需要先把与Elasticsearch相关的文件夹的操作权限赋给非root用户(这里是xiaoming组中的xiaoming用户),之后以xiaoming用户启动Elasticsearch服务。
    第六步,测试Elasticsearch。
    在浏览器中输入"http://10.211.55.4:9200"进行访问或者在服务器上使用:
    curl -X GET "http://10.211.55.4:9200"
    访问Elasticsearch,返回如下结果,表示Elasticsearch安装成功!
    {
        "name" : "node-es-1",
        "cluster_name" : "mymicroservice-elk",
        "version": {
                "number" : "2.4.0",
                "build_hash" : "ce9f0c7394dee074091dd1bc4e9469251181fc55",
                "build_timestamp": "2016-08-29T09:14:17Z",
                "build_snapshot":"false",
                "lucene_version":"5.5.2"
            },
        "tagline":"You Konw,for search"
    }
    2.3 安装配置启动Logstash-Shipper
    第一步,在开发机下载logstash-2.4.0.tar.gz,下载地址为:https://www.elasticsearch.co/downloads。
    第二步,将在开发机下载好的logstash-2.4.0.tar.gz复制到10.211.55.4.
    scp logstash-2.4.0.tar.gz root@10.211.55.4:/opt/
    第三步,解压安装。
    cd /opt/
    tar -zxf logstash-2.4.0/ /opt/logstash-shipper
    第五步,创建并添加配置文件
    cd /opt/logstash-shipper/
    mkdir conf
    cd conf/
    touch logstash.conf
    vi logstash.conf
    添加如下配置:
    input{
        tcp{
            mode=> "server"
            host=> "10.211.55.4"
            port=> "4560”
            codec=> "json_lines"
        }
    }
    filter{
    }
    output{
        redis{
            data_type=>"list"
            host=>["10.211.55.4:6379]
            key=>"microservice:logstash:redis"
        }
    }
    这里,配置了Logstash的三要素:input,filter和output。input指定数据从哪里来,filter对数据进行过滤处理,output指定将处理后的数据发送到哪里去。Logstash提供了很多的input、filter、output插件。
    这里使用的input插件是rcp插件。
    mode:可选server或client。server表示监听客户端连接;client表示去连接server。
    host:监听的host
    port:监听的端口
    codec:对输入数据进行编解码,转换格式,这样,就不需要在filter中做这个事儿了。"json_lines"是对有换行符("\n")的json串进行编解码,"json"是对没使用的输出插件是Redis串进行编解码。
    使用的输出插件是Redis插件。
    data_type:可选list、channel或pattern_channel。这里使用了list,之后使用blpop命令处理Redis内的元素。blpop是lpop的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被blpop命令所阻塞。
    host:Redis server的地址。
    key:这里是list的名字。
    第六步,启动Logstash-Shipper。
    nohup /opt/logstash-shipper/bin/logstash -f /opt/logstash-shipper/conf/logstash.conf &
    这里使用"-f"指定启动的时候读取的配置文件。
    2.4 安装配置启动Logstash-Indexer
    第一步,解压安装
    cd /opt/
    tar -zxf logstash-2.4.0.tar.gz
    第二步,重命名解压好的包
    mv /opt/logstash-2.4.0/ /opt/logstash-indexer
    第三步,创建并添加配置文件。
    cd /opt/logstash-indexer/
    mkdir conf
    cd conf/
    touch logstash.conf
    vi logstash.conf
    添加如下配置:
    input{
        tcp{
            mode=> "list"
            host=> "10.211.55.4"
            port=> "6379”
            codec=> "microservice:logstash:redis"
        }
    }
    filter{
    }
    output{
        redis{
            hosts=>["10.211.55.4:9200]
            index=>"logstash-%{YYYY.MM.dd}"
        }
    }
    这里,同样配置了Logstash的三要素:input、filter和output。使用的input插件是Redis插件,各个选项意义与Shipper中的相同。
    使用的输出插件是Elasticsearch插件。    
    host:Elasticsearch集群的地址,如果有多个节点,节点之间使用","分割。注意,在该集群中,最好只配置elasticsearch的client节点。
    index:指定数据发到哪一个索引中去。默认使用"logstash-%{YYYY.MM.dd}"做索引。
        按照天来分片,方便我们按照天来查询和删除存储的日志数据。
        在语法解析的时候,看到以+号开头的,会自动认为后面是时间格式,尝试用时间格式来解析后续字符串。所以,不要给自定义的字段起一个以+号开头的名字。
        索引名中不能有大写字母
        有时也会自定义为logstash-%{servicename}-%{+YYYY.MM.dd},在索引中添加服务名。
    第四步,启动Logstash-Indexer。
    nohup /opt/logstash-indexer/bin/logstash -f /opt/logstash-indexer/conf/
    logstash.conf &
    2.5 安装配置启动Kibana
    第一步,在开发机下载kibana-4.6.1-linux-x86-64.tar.gz,下载地址为:https://www.elastic.co/downloads。
    第二步,将在开发机下载好的kibana-4.6.1-linux-x86_64.tar.gz复制到10.211.55.4/
    scp kibana-4.6.1-linux-x86_64.tar.gz root@10.211.55.4:/opt/    
    第三步,解压安装。
    cd /opt/
    tar -zxf kibana-4.6.1-linux-x86_64.tar.gz
    第四步,修改配置文件。
    vi /opt/kibana-4.6.1-linux-x86_64/config/kibana.yml
    修改如下配置:
    修改如下配置:
    server.host:"10.211.55.4"
    server.port:5601
    elasticsearch.url:http://10.211.55.4:9200
    这里,server.host和 server.port指定了Kibana的地址;elasticsearch.url指定了Kibana从哪些Elasticsearch节点中查询数据。
    nohup /opt/kibana-4.6.1-linux-x86_64/bin/kibana &
    第六步,测试Kibana。
    在浏览器中输入"http://10.211.55.4:5601"进行访问。当出现Kibana的页面时,表示Kibana启动成功!
3. 使用LogbackAppender发送日志
        Springboot默认选择Logback作为日志框架。所以这里我们准备使用LogbackAppender通过tcp协议来发送日志导ELK系统中。为什么不选择直接从日志文件提取数据 到
    Logstash-Shipper的方式来收集日志呢?因为这种方式需要在每一个服务器上都安装一个Logstash,比较麻烦,而使用tcp协议时不需要安装的;但是使用tcp协议需要写一些
    代码,看似对于每个服务都要 写这么一段代码,实际上,每个公司基本都会有自己的服务框架,把日志发送的这段代码写在其中,其他服务依赖于这个服务框架,这样写一遍
    就可以了。
    配置logback.xml
        通常,Logback的日志配置信息都会存放在logback.xml文件中,在Spring Boot中配置该文件非常简单。配置如下:
    Springboot默认选择Logback作为日志框架。在非web应用中,使用日志框架,需要引入spring-boot-start-logging,在web项目中,引入spring-boot-start-web就可以了。
    如果我们只是想改变某些日志的level,那么在logback.xml文件中,一般会引入org/springframework/boot/logging/logback/base.xml(该文件在https://github.com/spring-
    projects/spring-boot/blob/master/spring-boot/src/main/resources/org/springframework/boot/logging/logback/base.xml上),在该文件中,配置了很多信息,例如
    Tomcat的一些日志信息。引入之后,定义一些日志的级别就可以了,比如上边的<logger name="org.springframework.web" level="DEBUG"/>
    创建LogbackAppender发送日志
        在使用LogbackAppender向Logstash-Shipper发送日志信息之前,首先需要配置Logstash-Shipper和日志级别等相关信息,这些信息配置在application.properties中,
    内容如下:
    ogstash.shipper.host=10.211.55.4
    logstash.shipper.port=4560
    logstash.level=info
    这里配置了Logstash-Shipper的地址及日志级别(为info)。至于日志级别大于等于info的日志(例如,info、warn和error)才会被发送到Logstash,而debug级别的就不发送了。
    配置好Logstash和日志级别之后,创建一个LogbackAppender来发送日志到Logstash-Shipper。代码如下:
    首先,使用注解@PostConstruct注解指定startLogbackAppender()方法在该类实例化之后就开始执行;其次,tcpAppender内部使用了disruptor框架,disruptor是一个优秀
    的无锁框架,并且在该框架中日志的发送是异步的,所以不需要我们在程序中做异步处理;最后,想要理清startAppender()方法中的各个实例的层次结构,可参考:
    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <appender name="stash"
            class="net.logstash.logback.appender.logstashTcpSocketAppender">
            <destination>127.0.0.1:4560</destination>
            <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
        </appender>
        <root level="DEBUG">
            <appender-ref ref="stash"/>
        </root>
    </configuration>
        最后,总结一下startLogbackAppender()的流程。首先定义一个LogstashTcpSocketAppender的实例,名字为stash,发送到目的地为指定的Logstash-Shipper的地址;之后
    为了将数据输出为json串,创建了LogstashEncoder实例,并且指定了自定义的字段,这样就可以在Kibana中使用"service:'parent'"来查询日志。然后,将该encoder实例
    赋给stash。最后,将stash赋给Logback的rootLog,并指定记录日志的级别。
    在settings菜单下创建,因为我们在Logstash-Indexer中指定索引是"logstash-%{+YYYY.MM.dd}",所以这里需要在Index name or pattern文本框中输入"logstash-*",其它
    选项使用默认值,单击Create按钮,索引就创建成功了。创建好索引后,单击Discover菜单,在左侧选项选择相应的索引,之后就可以查看日志了
        到此为止,整个日志就搭建完成了。在实际使用中,对开发人员来讲,可能更需要关注的是怎么使用kibana来进行日志查询,因为系统的搭建会由运维人员来完成,日志发送代码
    会由架构组来完成。
4. Kibana常见用法
    4.1 日期选择
        单击右上角的时间区域,在Quick菜单下可以快速选择一些时间;在Relative菜单下可以选择从当前时间算起"前多少时间内"的时间(例如从现在算起,前30min内);在Absolute菜单下可以指定起始时间和终止
    时间点(精确到ms)。
    4.2 自动刷新
        单击右上角的时间区域后,单击Auto-refresh菜单。可以选择多长时间刷新一次(最快为5s,最慢为1天),默认选中off,即不自动刷新。
    4.3 查询语法
        在Kibana的顶部菜单栏下边有个搜索框,在该搜索框内可以根据Kibana的语法输入相关的表达式进行搜索。
        值得注意的是,在Chrome浏览器下,该搜索框有的时候不好用。所以使用Kibana时推荐换一个浏览器,例如safari。我们来看下Kibana最常见的几个查询方法。
        1. 按照日志数据去查:message:'小红'。
        2. 按照field查:service:'logstashservice'。
        3. 按照level去查:level:'ERROR'。
        4. 组合查询:service:'logstashservice' and level:'ERROR'。
        5. 通配符查询:getUser*或者getUser?。 *表示多个字符,?表示一个字符,也就是说getUserAge和getUser?不匹配。
        6. 全文搜索:直接在搜索框输入一个自己想要的日志串进行搜索(假设,要查询一个日志message中含有小红,则表达式是"小红",一定要用双引号)。
5. 使用Curator定时删除日志
    5.1 安装Curator
    第一步,添加yum源。
    tee /etc/yum.repos.d/curator.repo <<-'EOF'
    [curator-4]
    name=CentOS/RHEL 7 repository for Elasticsearch Curator 4.x packages
    baseurl=http://packages.elastic.co/curator/4/centos/7
    gpgcheck=1
    gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    EOF
    第二步,安装Curator。
    cd /opt/
    yum install elsticsearch-curator
    5.2 配置Curator
        Curator有两个配置文件:config.yml和action.yml。其中在config.yml中配置一些通用信息,例如Curator监督管理的Elasticsearch的hosts和port等;在action.yml中配置一些动作信息,例如删除60天前的日志文件等。
    cd /opt/elasticsearch-curator/
    mkdir config
    之后创建config.yml
    cd config/
    vi config.yml
    添加如下内容:
    ---
    #Remember,level a key empty if there is no value.none will be a string,
    #not a Python "NoneType"
    client:
        hosts:
         - 10.211.55.4
        port: 9200
        url_prefix:
        use_ssl: False
        certificate:
        client_cert:
        client_key:
        ssl_no_validate:False
        http_auth:
        timeout:30
        master_only:False
    logging:
        loglevel: INFO
        logfile:
        logformat:dafault
        blacklist:['elasticsearch','urllib3']
        在该配置文件中,比较重要的是Elasticsearch的hosts和port,其他采用默认值即可(注意,如果没有值,需要置空)。该配置文件可以到Elasticsearch的官网:https://www.elastic.co/guide/en/elasticsearch/client/curator/4.1/configfile.html下载。
        之后再/opt/elasticsearch-curator/config创建action.yml。
        vi action.yml
        添加如下内容:
        ---
    #Remember,level a key empty if there is no value.none will be a string,
    #not a Python "NoneType"
    #
    #Also remember that all examples have 'disable_action' set to true.If you want to use this action as a template,be sure to set this to False after coping it
    actions:
    1:
        action:delete_indices
        description:"Delete indices older than 1 days(based on index name),for logstash- prefixed indices.
            Ignore the error if the filter does not result in an actionable list of indices(ignore_empty_list) and exit cleanly"
            options:
                timeout_override:
                continue_if_exception:False
                disable_acion:False
            filters:
            - filtertype:pattern
                kind:prefix
                value:logstash-
                exclude:
            - filtertype:age
                source:name
                direction:older
                timestring:'%Y.%m.%d'
                unit:days
                unit_count:1
                exclude:
        在该配置文件中,只有一个action,用于删除索引。这里指定了删除前缀是"logstash-"并且日期是一天前的索引。该配置文件也可以到Elasticsearch的官网:https://www.elasric.co/guide/en/elasticsearch/client.curator/4.1/actionfile.html下载。
    5.3 配置crontab定时任务
        首先编写一个Shell脚本:
        cd /opt/elasticsearch-curator
        vi curator-delete-index.sh
        添加如下内容:
        #! /bin/sh
        echo "start delete data"
        /opt/elasticsearch-curator/curator --config/opt/elasticsearch-curator/config/config.yml /opt/elasticsearch-curator/config/action.yml
        echo "delete data sucess"
        在该Shell脚本中,使用Curator删除索引,然后,给该脚本赋予执行权限。
        chmd 777 /opt/elasticsearch-curator/curator-delete-index.sh
        最后,创建定时任务来执行脚本。
        crontab -e
        打开vi,输入:
        20 21 * * * /opt/elasticsearch-curator/curator-delete-index.sh
        该定时任务指定每天的21点20分执行脚本。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方的、远方的、、、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值