Sleuth微服务链路追踪整合ELK和zipkin

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
可观测链路 OpenTelemetry 版,每月50GB免费额度
简介: Sleuth微服务链路追踪整合ELK和zipkin

1 分布式计算八大误区

网络可靠。

延迟为零。

带宽无限。

网络绝对安全。

网络拓扑不会改变。

必须有一名管理员。

传输成本为零。

网络同质化。(操作系统,协议)

2 链路追踪的必要性

如果能跟踪每个请求,中间请求经过哪些微服务,请求耗时,网络延迟,业务逻辑耗时等。我们就能更好地分析系统瓶颈、解决系统问题。因此链路跟踪很重要。


我们自己思考解决方案:在调用前后加时间戳。捕获异常。


链路追踪目的:解决错综复杂的服务调用中链路的查看。排查慢服务。


市面上链路追踪产品,大部分基于google的Dapper论文。

zipkin,twitter开源的。是严格按照谷歌的Dapper论文来的。
pinpoint 韩国的 Naver公司的。
Cat 美团点评的
EagleEye 淘宝的

3 链路追踪要考虑的几个问题

  1. 探针的性能消耗。尽量不影响 服务本尊。
  2. 易用。开发可以很快接入,别浪费太多精力。
  3. 数据分析。要实时分析。维度足够。

4 Sleuth简介

Sleuth是Spring cloud的分布式跟踪解决方案。


span(跨度),基本工作单元。一次链路调用,创建一个span,


span用一个64位id唯一标识。包括:id,描述,时间戳事件,spanId,span父id。


span被启动和停止时,记录了时间信息,初始化span叫:root span,它的span id和trace id相等。


trace(跟踪),一组共享“root span”的span组成的树状结构 称为 trace,trace也有一个64位ID,trace中所有span共享一个trace id。类似于一颗 span 树。


annotation(标签),annotation用来记录事件的存在,其中,核心annotation用来定义请求的开始和结束。


CS(Client Send客户端发起请求)。客户端发起请求描述了span开始。

SR(Server Received服务端接到请求)。服务端获得请求并准备处理它。SR-CS=网络延迟。

SS(Server Send服务器端处理完成,并将结果发送给客户端)。表示服务器完成请求处理,响应客户端时。SS-SR=服务器处理请求的时间。

CR(Client Received 客户端接受服务端信息)。span结束的标识。客户端接收到服务器的响应。CR-CS=客户端发出请求到服务器响应的总时间。

其实数据结构是一颗树,从root span 开始。

5 快速入门

5.1 Sleuth入门搭建

api_gateway_server 工程模块基础上扩展

5.1.1 引入坐标

<!--sleuth链路追踪-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

5.1.2 yml配置

各个微服务的yml配置文件都要加入日志

logging:
  level:
    root: info
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
  • 每个微服务都需要添加如上的配置

5.1.3 访问测试

  • 启动微服务并调用,可以在控制台观察到sleuth的日志输出

其中7c8d741c36af2723是TraceId,后面的是SpanId,依次调用有一个全局的TraceId,将调用链路串起来。仔细分析每个微服务的日志,不难看出请求的具体过程。

查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过Zipkin可以将日

志聚合,并进行可视化展示和全文检索

各个服务的控制台都可以看到日志的输出

6 项目整合Zipkin

6.1 docker 安装 zipkin

docker run -d -p 9411:9411 openzipkin/zipkin

6.2 在pom中添加依赖

 <!--zipkin 依赖也同时包含了 sleuth,可以省略 sleuth 的引用-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>

6.3 在application.yml添加如下配置

spring:
  zipkin:
    base-url: http://192.168.2.190:9411/  # zipkin 服务器的地址
    discovery-client-enabled: false # 关闭服务发现,否则 Spring Cloud 会把 zipkin 的 url 当做服务名称
    sender:
      type: web # 设置使用 http 的方式传输数据
  sleuth:
    sampler:
      probability: 1  # 设置抽样采集率为 100% ,默认为 0.1 ,即 10%

6.4 本地测试

启动项目,所有功能都跑一遍,然后访问 zipkin 服务器地址,显示如下:

7 sleuth+elk聚合日志

sleuth配置

  • 在微服务项目引入下列依赖
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
  • 配置文件application.yml增加
logging:
  level:
    root: INFO
    org.springframework.web.servlet.DispatcherServlet: DEBUG
    org.springframework.cloud.sleuth: DEBUG
  • 依次启动hello项目helloworld项目,在浏览器输入http://localhost:8020/message后两个项目的控制台输出如下日志

helloworld日志


hello 日志.png


其中a7c81616d25c1a88是TraceId,后面跟着的是SpanId,依次调用有一个全局的TraceId,将调用链路串起来。


查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,通过ELK可以将日志聚合,并进行可视化展示和全文检索。

sleuth配合elk使用


ELK是一款日志分析系统,它是Logstash+ElasticSearch+Kibana的技术组合,它可以通过logstash收集各个微服务日志,并通过Kibana进行可视化展示,而且还可以对大量日志信息通过ElasticSearch进行全文检索。


5f889695836480fff3621e987985a1d1.png

ELK.png

操作步骤:

  • 安装ELK,我使用了docker安装了ELK,具体安装步骤可参考这篇文章:

Docker部署es和kibana

区别是在启动logstash时,指定了日志来源路径

/opt/logstash/bin/logstash -e 
'input { file { codec => json path => "/opt/build/*.json" } } 
output { elasticsearch { hosts => ["localhost"] } }'
  • 项目添加依赖
      <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>4.9</version>
        </dependency>
  • 在src/java/resources目录下新建logback-spring.xml,配置如下内容
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <springProperty scope="context"
                    name="springAppName"
                    source="spring.application.name"/>
    <property name="LOG_FILE"
              value="${BUILD_FOLDER:-build}/${springAppName}"/>
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p})
              %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan}
              %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="filelog"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>7</MaxHistory>
        </rollingPolicy>
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <!-- 使用json格式保存日志文件 -->
    <appender name="jsonlog"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>7</MaxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        "severity": "%level",
                        "service": "${springAppName:-}",
                        "trace": "%X{X-B3-TraceId:-}",
                        "span": "%X{X-B3-SpanId:-}",
                        "parent": "%X{X-B3-ParentSpanId:-}",
                        "exportable": "%X{X-Span-Export:-}",
                        "pid": "${PID:-}",
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="jsonlog"/>
        <appender-ref ref="filelog"/>
    </root>
</configuration>

因为上面的日志文件用到spring.application.name,所以需要项目名称的配置挪到bootstrap.yml。


测试结果,在浏览器输入http://localhost:8020/message发起几次调用后,打开http://localhost:5601后看到上述的Kibana页面,说明可以正常使用ELK查询,分析跟踪日志。

相关实践学习
基于OpenTelemetry构建全链路追踪与监控
本实验将带领您快速上手可观测链路OpenTelemetry版,包括部署并接入多语言应用、体验TraceId自动注入至日志以实现调用链与日志的关联查询、以及切换调用链透传协议以满足全链路打通的需求。
分布式链路追踪Skywalking
Skywalking是一个基于分布式跟踪的应用程序性能监控系统,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据,提供了一种简便的方式来清晰地观测分布式系统,具有分布式追踪、性能指标分析、应用和服务依赖分析等功能。 分布式追踪系统发展很快,种类繁多,给我们带来很大的方便。但在数据采集过程中,有时需要侵入用户代码,并且不同系统的 API 并不兼容,这就导致了如果希望切换追踪系统,往往会带来较大改动。OpenTracing为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。Skywalking基于OpenTracing规范开发,具有性能好,支持多语言探针,无侵入性等优势,可以帮助我们准确快速的定位到线上故障和性能瓶颈。 在本套课程中,我们将全面的讲解Skywalking相关的知识。从APM系统、分布式调用链等基础概念的学习加深对Skywalking的理解,从0开始搭建一套完整的Skywalking环境,学会对各类应用进行监控,学习Skywalking常用插件。Skywalking原理章节中,将会对Skywalking使用的agent探针技术进行深度剖析,除此之外还会对OpenTracing规范作整体上的介绍。通过对本套课程的学习,不止能学会如何使用Skywalking,还将对其底层原理和分布式架构有更深的理解。本课程由黑马程序员提供。
目录
相关文章
|
3月前
|
存储 监控 Go
带你十天轻松搞定 Go 微服务系列(九、链路追踪)
带你十天轻松搞定 Go 微服务系列(九、链路追踪)
|
11天前
|
存储 NoSQL 关系型数据库
微服务Zipkin链路追踪原理,图解版,一文吃透!
本文重点讲解Zipkin链路追踪的原理与使用,帮助解决微服务架构下的服务响应延迟等问题,提升系统性能与稳定性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
微服务Zipkin链路追踪原理,图解版,一文吃透!
|
1月前
|
监控 Java 对象存储
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
41 1
|
3月前
|
数据可视化 Java Nacos
Sleuth+Zipkin 实现 SpringCloud 链路追踪
【8月更文挑战第9天】Sleuth+Zipkin 实现 SpringCloud 链路追踪
93 1
Sleuth+Zipkin 实现 SpringCloud 链路追踪
|
3月前
|
Kubernetes 监控 API
微服务从代码到k8s部署应有尽有系列(十二、链路追踪)
微服务从代码到k8s部署应有尽有系列(十二、链路追踪)
|
4月前
|
存储 监控 Java
zipkin 与 sleuth 实现链路追踪
zipkin 与 sleuth 实现链路追踪
69 0
|
5月前
|
存储 消息中间件 Java
【分布式链路追踪技术】sleuth+zipkin
【分布式链路追踪技术】sleuth+zipkin
70 2
|
2月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
2月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
1天前
|
消息中间件 供应链 架构师
微服务如何实现低耦合高内聚?架构师都在用的技巧!
本文介绍了微服务的拆分方法,重点讲解了“高内聚”和“低耦合”两个核心设计原则。高内聚强调每个微服务应专注于单一职责,减少代码修改范围,提高系统稳定性。低耦合则通过接口和消息队列实现服务间的解耦,确保各服务独立运作,提升系统的灵活性和可维护性。通过领域建模和事件通知机制,可以有效实现微服务的高效拆分和管理。
16 7
下一篇
无影云桌面