微服务架构中的日志和监控:ELK Stack实战

170 阅读5分钟

在微服务的海洋中遨游,没有一套靠谱的日志和监控系统,就像是蒙着眼睛在深海潜水 —— 刺激是刺激了,但下一秒可能就被鲨鱼咬掉小JJ。今天,让我们来聊聊如何用ELK Stack这把瑞士军刀,在微服务的汪洋大海中杀出一条血路。

为什么需要集中式日志系统?

想象一下,你有50个微服务,分布在100台服务器上。某天半夜,你被老板的电话叫醒(没错,always happens at midnight),说系统出了问题。你揉着惺忪的睡眼,开始一台一台地登录服务器,一个一个地查看日志文件。等你终于找到问题所在,天都亮了,而你的黑眼圈已经可以去竞选熊猫大使了。

这就是为什么我们需要集中式日志系统。它能让你在一个地方查看所有服务的日志,就像是给了你一双透视眼,能够洞察整个系统的运行状况。

ELK Stack简介

ELK是Elasticsearch、Logstash和Kibana的首字母缩写,就像是超级英雄联盟,各自都有独特的超能力:

  • Elasticsearch:分布式搜索引擎,数据存储的大脑。
  • Logstash:日志收集处理引擎,数据的大动脉。
  • Kibana:可视化平台,让数据变得性感的颜值担当。

后来,这个联盟又加入了一位新成员Beats,于是ELK Stack摇身一变,成了Elastic Stack。但我们还是习惯叫它ELK,就像你还是会叫"旺旺雪饼",而不是"旺旺仙贝"一样。

实战:搭建ELK Stack

好了,废话不多说,让我们开始动手吧。我们将以一个简单的Spring Boot微服务为例,演示如何将其日志接入ELK Stack。

步骤1:准备环境

首先,确保你的机器上安装了Docker。我们将使用Docker来快速搭建ELK环境。

创建一个docker-compose.yml文件:

version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.0
    environment:
      - discovery.type=single-node
    ports:
      - 9200:9200
  
  logstash:
    image: docker.elastic.co/logstash/logstash:7.10.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - 5000:5000
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:7.10.0
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch

步骤2:配置Logstash

创建logstash.conf文件:

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

filter {
  # 可以在这里添加一些过滤规则
}

output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "springboot-logs-%{+YYYY.MM.dd}"
  }
}

这个配置文件告诉Logstash监听5000端口,接收JSON格式的日志,然后将其发送到Elasticsearch。

步骤3:配置Spring Boot应用

在你的Spring Boot应用的pom.xml中添加以下依赖:

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

然后,在resources目录下创建logback-spring.xml

<configuration>
    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:5000</destination>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <root level="INFO">
        <appender-ref ref="LOGSTASH" />
    </root>
</configuration>

这个配置告诉你的应用将日志发送到Logstash。

步骤4:启动ELK Stack

运行以下命令启动ELK Stack:

docker-compose up -d

步骤5:生成一些日志

在你的Spring Boot应用中添加一些日志输出:

@RestController
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/hello")
    public String hello() {
        logger.info("Hello endpoint called");
        return "Hello, ELK!";
    }
}

步骤6:在Kibana中查看日志

  1. 打开浏览器,访问http://localhost:5601
  2. 进入Kibana后,创建一个index pattern,匹配springboot-logs-*
  3. 转到Discover页面,你应该能看到你的应用日志了

进阶技巧

1. 使用Filebeat

如果你有很多服务,每个服务都直接发送日志到Logstash可能会造成网络压力。这时,你可以考虑使用Filebeat。Filebeat是一个轻量级的日志收集器,可以安装在每台服务器上,收集日志文件,然后发送到Logstash。

2. 日志结构化

尽量使用结构化的日志格式,比如JSON。这样可以更容易地在Kibana中进行搜索和分析。

logger.info("Order processed", 
    kv("orderId", order.getId()), 
    kv("amount", order.getAmount()), 
    kv("status", "SUCCESS")
);

3. 使用Elasticsearch的聚合功能

Elasticsearch不仅仅是一个搜索引擎,它还有强大的聚合功能。你可以用它来做一些简单的统计,比如每分钟的错误日志数量:

GET /springboot-logs-*/_search
{
  "aggs": {
    "errors_over_time": {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "minute"
      },
      "aggs": {
        "error_count": {
          "filter": {
            "term": {
              "level": "ERROR"
            }
          }
        }
      }
    }
  }
}

4. 设置告警

你可以使用Elasticsearch的Watcher功能(付费功能)或者开源的ElastAlert来设置告警。比如,当错误日志数量在5分钟内超过100条时,发送一个告警。

结语

ELK Stack就像是给你的微服务装上了一个黑匣子,不管发生什么,你都能回溯、分析。但请记住,再好的工具也需要正确的使用。日志不是用来事后诸葛亮的,而是应该帮助你提前发现问题。所以,定期查看日志,设置合理的告警,才能真正发挥ELK Stack的威力。

最后,如果你觉得ELK Stack还不够酷,那就等着看Elastic在下一个版本中加入AI功能吧。到时候,也许你就可以直接问:"嘿,Elastic,昨晚系统为什么挂了?"然后它会回答:"因为你的代码写得太烂了,建议重新学习编程。"

好了,今天的课程到此结束。记住,在微服务的世界里,没有日志,就等于在裸奔。所以,穿上你的ELK盔甲,勇敢地面对那些令人头疼的问题吧!

海码面试 小程序

包含最新面试经验分享,面试真题解析,全栈2000+题目库,前后端面试技术手册详解;无论您是校招还是社招面试还是想提升编程能力,都能从容面对~