分布式常见面试题:谈谈分布式下的日志系统
在程序员面试中,“分布式下的日志系统设计”是高频面试题。今天,咱们就来详细聊聊这个话题,帮助大家深入理解分布式日志系统的原理、应用以及常见的实现方式。
日志在开发各环节的重要作用
在日常的开发、测试以及生产环境里,日志都发挥着极为关键的作用。当程序出现错误需要排查问题时,日志就像是“破案线索”,能帮我们定位出错的地方;在分析接口性能,计算接口响应时间的时候,日志里记录的时间戳等信息能提供关键数据;甚至在进行系统监控,掌握系统运行状态时,日志也不可或缺。
在项目开发过程中,我们常常会引入一些日志组件,比如log4j
、slf4j
等。在代码的关键位置添加日志记录,方便记录程序运行时的各种信息。
在本地环境下,写日志相对轻松,即使记录得随意一些,对整体开发影响也不大。但在线上环境中,日志却成为了定位问题的重要工具。在单体架构里,因为只有一台机器,通过tail -f
命令就能轻松监控日志。然而,当架构发展到集群架构,尤其是微服务架构时,情况就变得复杂起来。各个服务分布在不同的服务器上,服务之间还存在交叉调用。此时,想要查看一个事务的完整日志,可能需要登录好几台服务器,逐个查找相关信息,十分麻烦。
分布式日志框架的出现与主流框架介绍
为了解决分布式架构下日志管理的难题,一系列分布式日志框架应运而生,其中ELK是比较主流的一种。ELK并非单一的工具,而是由Logstash
、Elasticsearch
(简称ES)和Kibana
这三个组件共同构成。
Logstash
主要负责日志的收集、过滤和上报工作。它就像是一个勤劳的“快递员”,在各个服务器之间穿梭,把分散的日志收集起来,并且在收集过程中可以对日志进行过滤处理,剔除一些不需要的信息,然后将处理后的日志上报到指定的地方。
ES则承担着存储和搜索日志的重任。它像一个巨大的“仓库”,把Logstash
上报过来的日志妥善存储起来,同时还具备强大的搜索功能,方便我们快速找到想要的日志信息。
Kibana
为我们提供了日志查询的可视化界面。有了它,我们无需在命令行中输入复杂的命令来查询日志,直接通过直观的可视化界面,就能轻松查看、分析日志数据。
如今,Filebeat
逐渐被引入,用来替代Logstash
做日志收集工作。Filebeat
有两个突出优点:一是专业性强,它专门用于日志收集,能够像tail -f
一样实时监听正在打印的日志,还支持接收消息队列里的日志数据,并且可以同时处理多个数据源的日志;二是它非常轻量,不像Logstash
运行在JVM里会占用较多资源。在一些场景中,如果不需要对数据进行清洗,甚至可以直接去掉Logstash
,形成“FEK”架构。但要是数据需要清洗,就还得借助Logstash
这个日志清洗的中间件,此时采用“FELK”架构更为合适。
分布式日志系统的实现策略
在实际项目中,对于常见的方法访问日志,除了使用常规的写日志方式,还可以借助注解和AOP(面向切面编程)的方式来实现。通过这种方式,在方法执行时,就像在关键路口设置了“监控摄像头”,可以拦截访问记录,然后通过消息队列把这些记录发送到ES或其他日志库进行存储。
基于日志,我们还能实现链路追踪。简单来说,在一次事务开始时,会生成一个唯一的“trace id”,就好比给这次事务发放了一张“通行证”。后续,按照请求的顺序对相关操作进行编号,这样就能把整个业务调用链路清晰地串联起来。通过查看这个链路,我们可以清楚地知道访问了哪些方法,方法里的关键业务逻辑、请求外部资源的情况以及输入输出参数等信息。
当然,也有人会提出疑问,觉得使用注解和AOP方式实现链路追踪存在代码侵入的问题,认为使用Pinpoint
或Zipkin
这类工具会更好。不可否认,使用这些工具确实能把整个链路串起来,但在实际查看链路时,通过Pinpoint
等工具生成的链路信息可能会过于繁杂。在实际排查问题时,我们往往更关注业务逻辑以及关键变量的数据状态变化,而这种情况下,传统的日志查询方式反而能更精准地满足需求。
分布式日志系统是分布式架构中非常重要的一环,希望通过本文的介绍,大家能对其有更深入的理解。如果对文章内容有任何疑问,欢迎在评论区留言交流。