skywalking链路追踪时忽略指定异常

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
简介: skywalking链路追踪时忽略指定异常

一、介绍

在前面介绍在微服务项目中使用skywalking进行全链路追踪时,我们发现当一次请求链路中某个服务出现异常时,在skywalking中会将该链路用红色标记为ERROR,在异常链路详情中也可以看出是哪个服务出现了异常并可以查看响应的异常信息。如下图所示。

商品id为5的调用链路界面.png

那么有没有办法忽略某个指定的异常呢?就是说如果一个请求链路中某个服务抛出了该异常,skywalking仍然认为该异常属于正常现象,并不会认为它是ERROR

答案是肯定的。我们往下看。

二、演示项目介绍

项目结构依然参考skywalking安装教程中的演示项目,业务流程就是商品服务暴露接口给客户端,当客户端调用商品服务接口时,商品服务调用订单服务,订单服务调用支付服务,形成一个包含三个服务的调用链。如下图所示。

微服务项目架构图.png

1. 支付服务

现在我们定义两个异常:SixExceptionSevenException,其中SixException 继承 SevenExceptionSevenException继承RuntimeException,也就是说我们自定义的两个异常都是运行时异常。结构如下。

自定义异常的结构图.png

当接口接收的参数goodsId为6的倍数时,抛出SixException;当参数goodsId为7的倍数时则抛出SevenException。如下所示

  • SevenException

    @Slf4j
    public class SixException extends SevenException{
         
    
        public SixException(String message) {
         
            super(message);
        }
    }
    
  • SixException

    @Slf4j
    public class SevenException extends RuntimeException{
         
    
        public SevenException(String message) {
         
            super(message);
        }
    }
    
  • 修改接口

    @GetMapping("/pay")
    public Integer pay(@RequestParam("goodsId") Integer goodsId) {
         
        log.info("支付服务feign接口,服务端口号:{}", port);
        log.info("商品id:{}", goodsId);
        if (goodsId % 6 == 0) {
         
            log.error("商品id不允许为6的倍数");
            throw new SixException("商品id不允许为6的倍数");
        }
        if (goodsId % 7 == 0) {
         
            log.error("商品id不允许为7的倍数");
            throw new SevenException("商品id不允许为7的倍数");
        }
    
        return 0;
    }
    
  • 添加全局异常处理器

    我们将抛出SevenException这个异常的情况定义为正常情况,当接口抛出SevenException时,通过全局异常处理器捕获该异常,然后将接口响应设置为失败即可。

    @RestControllerAdvice
    public class GlobalExceptionHandlers {
         
    
        @ExceptionHandler(SixException.class)
        public Integer sixException(SixException e) {
         
            return 1;
        }
    
        @ExceptionHandler(SevenException.class)
        public Integer sevenException(SevenException e) {
         
            return 1;
        }
    }
    

2. 订单服务

在原本的订单服务的接口中,有个判断条件为如果商品id为2的倍数,则返回。该条件影响我们支付服务中对SixException的测试,所以该判断条件删除,如下所示

订单服务接口.png

三、项目演示

下面我们按部就班启动微服务项目和skywalking服务,并调用商品服务接口,分别传入商品id为6和7的参数。

  • 商品id为6

    请求如图

    商品id为6的请求.png

日志如图

商品id为6的日志.png

  • 商品id为7

    请求如图

    商品id为7的请求.png

日志如图

![商品id为7的日志.png](https://ucc.alicdn.com/pic/developer-ecology/een7m2naevh4a_11ef736d049b4e8bb4068b20159af40f.png)

1. 未忽略异常

在未忽略异常的情况下,skywalking将出现异常的链路以及出现异常的服务均使用红色标记为ERROR

请求参数商品id分别为6和7的调用链路如下

  • 商品id为6的请求链路

    商品id为6的请求链路.png

  • 商品id为7的请求链路

    商品id为7的请求链路.png

2. 忽略异常

有时候抛出异常是控制代码运行的重要方式,因此我们需要对这类异常进行忽略。skywalking提供了两种方式:修改配置使用注解

修改配置

agent.config配置文件中找到statuscheck.ignored_exceptions对其进行配置,当然了配置方式有多种:修改配置文件jvm启动参数javaagent选项操作系统环境变量,这四种配置方式我们在[skywalking安装教程]中已经详细介绍过了。这里以修改jvm启动参数为例,当需要忽略多个异常时,使用逗号“,”分隔。如下所示。

jvm参数忽略SevenException.png

修改完成后重新启动支付服务,然后再分别调用商品id为6和商品id为7两个请求,得到的调用链路如下

  • 商品id为6的请求链路

忽略SevenException的商品id为6的调用链路.png

  • 商品id为7的请求链路

    忽略SevenException的商品id为7的调用链路.png

从截图可以发现,当我们在某个服务中忽略指定的异常时,skywalking会将出现该异常的服务标记为成功。而且,我们忽略的异常明明是SevenException,但是当出现SixException时,skywalking也会对其进行忽略。

所以得出结论:当忽略一个指定的父异常时,skywalking会忽略该父异常和它的子异常。

使用注解

skywalking也提供了通过注解的方式来指定一个忽略的异常。

  • 添加依赖

    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-trace</artifactId>
        <version>8.9.0</version>
    </dependency>
    
  • 在要忽略的异常上添加注解@IgnoredException,等同于添加配置statuscheck.ignored_exceptions

    @IgnoredException
    public class SevenException extends RuntimeException{
         
    
        public SevenException(String message) {
         
            super(message);
        }
    }
    

四、结论

  • 通过给微服务添加statuscheck.ignored_exceptions=异常类的限定路径,实现在调用链路中忽略指定异常。
  • 通过注解@IgnoredException指定要忽略的异常,但需要添加依赖apm-toolkit-trace
  • 当忽略一个指定的父异常时,skywalking会忽略该父异常和它的子异常。




纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

相关实践学习
基于OpenTelemetry构建全链路追踪与监控
本实验将带领您快速上手可观测链路OpenTelemetry版,包括部署并接入多语言应用、体验TraceId自动注入至日志以实现调用链与日志的关联查询、以及切换调用链透传协议以满足全链路打通的需求。
分布式链路追踪Skywalking
Skywalking是一个基于分布式跟踪的应用程序性能监控系统,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据,提供了一种简便的方式来清晰地观测分布式系统,具有分布式追踪、性能指标分析、应用和服务依赖分析等功能。 分布式追踪系统发展很快,种类繁多,给我们带来很大的方便。但在数据采集过程中,有时需要侵入用户代码,并且不同系统的 API 并不兼容,这就导致了如果希望切换追踪系统,往往会带来较大改动。OpenTracing为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。Skywalking基于OpenTracing规范开发,具有性能好,支持多语言探针,无侵入性等优势,可以帮助我们准确快速的定位到线上故障和性能瓶颈。 在本套课程中,我们将全面的讲解Skywalking相关的知识。从APM系统、分布式调用链等基础概念的学习加深对Skywalking的理解,从0开始搭建一套完整的Skywalking环境,学会对各类应用进行监控,学习Skywalking常用插件。Skywalking原理章节中,将会对Skywalking使用的agent探针技术进行深度剖析,除此之外还会对OpenTracing规范作整体上的介绍。通过对本套课程的学习,不止能学会如何使用Skywalking,还将对其底层原理和分布式架构有更深的理解。本课程由黑马程序员提供。
相关文章
|
3月前
|
消息中间件 Java 中间件
链路跟踪-SkyWalking系列(三)
链路跟踪-SkyWalking系列(三)
|
3月前
|
监控 Java Shell
链路跟踪-SkyWalking系列(一)
链路跟踪-SkyWalking系列(一)
|
3月前
|
存储 缓存 数据可视化
链路跟踪-SkyWalking系列(二)
链路跟踪-SkyWalking系列(二)
|
存储 机器学习/深度学习 运维
基础篇丨链路追踪(Tracing)其实很简单(3)
基础篇丨链路追踪(Tracing)其实很简单
201 0
基础篇丨链路追踪(Tracing)其实很简单(3)
|
存储 运维 监控
基础篇丨链路追踪(Tracing)其实很简单(2)
基础篇丨链路追踪(Tracing)其实很简单
166 0
基础篇丨链路追踪(Tracing)其实很简单(2)
|
存储 NoSQL Java
链路跟踪Jaeger使用总结
链路跟踪Jaeger使用总结
176 0
|
数据采集 调度 数据库
基础篇丨链路追踪(Tracing)其实很简单(1)
基础篇丨链路追踪(Tracing)其实很简单
154 0
|
SQL 缓存 运维
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
6553 10
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
|
监控 Java BI
链路追踪Skywalking应用实战 1
链路追踪Skywalking应用实战
287 0
|
JSON 运维 监控
链路追踪Skywalking应用实战 2
链路追踪Skywalking应用实战
254 0