有句老话是无监控不运维,在平时进行应用运维或者监控时,我们需要通过一系列图表了解当前程序运行状态以及各个服务器的指标。
我们在Java领域已经有了相对标准的答案,即Elastic机构提供的三剑客。如果你对大数据或者互联网架构稍微了解一些,那么对Elastic三剑客应该不陌生。我们分别来介绍一下。
- 第一个是LogStash,它的作用是对日志进行集中处理、转换、过滤。
- 第二个是在Java中设计得最好的全文检索引擎以及数据运算引擎Elasticsearch。Elasticsearch的主要作用是对数据进行分析,生成各种统计图表以及运行时的指标信息。还提供了最强大的数据查询功能。
- 另一个工具是Kibana,一个可视化展现工具,帮助我们对Elasticsearch加工好的数据进行可视化展现。
这Elastic的三剑客,实际上构成了我们现在的第一个标准日志收集方案。
第一种方案-标准ELK
它的处理过程是在每台应用服务器上安装部署LogStash组件,实时收集每个应用产生的日志,并对日志进行收集、分析、整理,将处理好的数据发送给Elasticsearch进行数据运算,生成相应的统计图表和数据结果。这些数据结果被Kibana加载,我们可以在前台通过界面看到最终运行效果。
这三个中间件由同一家公司开发,集成度非常好,我们可以通过简单配置完成数据收集整理展现工作,这也是我们在早期Java领域使用最多的方案。
首先elk是结构最简单并且使用组件最少的方案。但Elk本身存在一些严重问题。问题在于LogStash是收集、解析、过滤处理于一身,因此它会消耗CPU以及内存资源。尤其针对当前的应用程序,它可能是计算密集型CPU,资源本来非常宝贵,结果还要增加LogStash对日志进行分析处理,这会导致单台服务器的性能下降,甚至影响整体系统的运行结果。因此我们作为LogStash并不会在应用服务器上部署它。
第二种方案TCP的推送方案。
LogStash是如此重量级的操作,我们不能将其放置在每台应用服务器中。
第二种方案是基于Java应用程序中的一款著名日志组件logback。Logback是我们在Java中使用最多的日志组件,用于生成和管理日志。logback它可以实时收集自己产生的日志,通过这款logstash-logback-encoder插件和TCP连接将数据发送给LogStash。每个应用服务器都按照这样做,当LogStash它会收到所有服务器的日志,按照时序顺序进行整理过滤,存储有效信息,Elasticsearch再进行统计分析,最后由Kibana进行展现。
方案2解决了方案一中LogStash资源占用问题。每个服务器上都会存在logback插件,它的职责是收集新产生的日志并通过TCP发送,不在服务器上进行任何运算工作。因此日志收集过程的开销非常小,不会对原有服务器造成很大负担。
方案二有优点和缺点,优点是减小了服务器压力,缺点非常明显。Logback本质上是Java中的一个jar包,基于SDK嵌入原有代码的方式进行操作。因此对于有侵入的代码需要进行修改。由于你在代码里写死并向LogStash发送,这将导致我们的应用与LogStash之间耦合。
如果我们某天不再使用LogStash或者选择其他更优秀的产品进行日志收集过滤分析,那么程序代码必须发生变更,这显然不是我们希望看到的结果。
第三种方案出现在互联网业界中,即最常用的efk,主要变更是在每台服务器上不再选择刚才的logback插件,而是更换为由Elastic自家出品的FileBeat组件。
方案3:EFK
FileBeat是轻量型日志收集器,主要职责是用于转发和集中日志数据的轻量级传输工具。FileBeat的执行原理是监视指定的日志文,并将其转发给LogStash进行索引和二次加工。
FileBeat实际上是一个文件监听器。我们在应用服务器上部署FileBeat之后,它会对我们配置好的指定配置文件进行监听。一旦产生新数据,它会收集并发送到我们配置好的某个数据源,例如可以发送到LogStash进行二次加工和筛选,或者直接发送给ES。当然,它还可以发送给kafka或者redis,这两项FileBeat支持。
FileBeat解决了侵入式问题,它采用文件监听方式,不会对原有程序代码产生任何影响。原有程序代码只需生成日志文件,额外部署的FileBeat组件就会监听数据。对于应用程序无侵入式,即使增加全新应用,只需在FileBeat增加额外的日志文件配置即可。
FileBeat的优点是占用资源少,代码无侵入,这是目前最常用的互联网应用日志架构。然而,FileBeat在设计初期的天生短板是只能配置一个输出源。按照刚才的架构图,由FileBeat收集到的数据,只能选择选一个,并不支持既往es发送,也同时向LogStash发送。
在这种情况下,针对大规模互联网应用存在一个短板。通常不同团队收集到的日志有不同用途,有的会将数据发往LogStash,有的会将数据发送给其他大数据平台。因此,FileBeat能做的事情非常有限。
第四种方案是解决多输出问题,我将其称为kefk。
方案4:KEFK
在原有基础上增加了kafka。kafka是消息队列,FileBeat收集日志后不再送达给某个具体日志处理组件,而是将其发送给kafka的消息队列。
kafka作为数据中转站,其他日志组件只需订阅kafka消息队列即可实现数据分发工作。因此,在原有日志架构中增加kafka,可以实现让FileBeat产生的数据通过kafka分发给其他数据处理组件,完成不同团队的日志分析处理需求。这是一个非常重要的设计,在互联网大规模应用下非常普遍。
这种设计有好也有坏,好的是性能最好,既无侵入,也通过消息队列分发数据。在这里它是最贵的,因为我们需要额外部署kafka集群,kafka面对日志时是高并发,单台服务器可靠性不足,性能不够,所以我们需要部署kafka集群,这样的成本很高。同时因为当前架构中增加了kafka,架构运维以及设计难度比原有的elk,efk大不少,所以这种情况下它的运维成本最大。
Kefk主要应用于互联网大体量应用。