skywalking忽略调用链路中的指定异常

文章目录

一、介绍

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

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

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

二、演示项目介绍

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

1. 支付服务

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

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

  • SevenException

    java 复制代码
    @Slf4j
    public class SixException extends SevenException{
    
        public SixException(String message) {
            super(message);
        }
    }
  • SixException

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

    java 复制代码
    @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时,通过全局异常处理器捕获该异常,然后将接口响应设置为失败即可。

    java 复制代码
    @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的测试,所以该判断条件删除,如下所示

三、项目演示

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

  • 商品id为6

    请求如图

    日志如图

  • 商品id为7

    请求如图

    日志如图

1. 未忽略异常

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

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

  • 商品id为6的请求链路

  • 商品id为7的请求链路

2. 忽略异常

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

修改配置

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

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

  • 商品id为6的请求链路

  • 商品id为7的请求链路

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

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

使用注解

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

  • 添加依赖

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

    java 复制代码
    @IgnoredException
    public class SevenException extends RuntimeException{
    
        public SevenException(String message) {
            super(message);
        }
    }

四、结论

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

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

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

相关推荐
wangchunyu1146 小时前
JAVA CompletableFuture异步编程实战
java·开发语言·python
paopaokaka_luck7 小时前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
Thomas.Sir7 小时前
第9课:SpringBoot4.x Web开发基础:WebMvc自动配置、静态资源、请求参数接收
java·spring boot
程序 代码狂人7 小时前
切片表与分区表的区别(数据开发面试版)
java·大数据·开发语言·数据仓库·算法
2501_944521598 小时前
Deepmerge 跨端三方库仓颉适配全流程
java·python·eclipse·github
南归北隐9 小时前
Spring AI Alibaba Graph框架实现MCP数据库查询实战
java·后端·spring ai·mcp·spring ai mcp
古法老登瞎折腾10 小时前
大数据智能运维实战(九):让 AI 查日志——找到异常,也保留上下文
java·大数据·运维·人工智能·spring ai·mcp
ai大模型-探索者10 小时前
Function Call与MCP(区别、联系与实战)
java·服务器·网络
略略略咯咯10 小时前
啊啊啊啊啊
java·服务器·数据库
SL_staff10 小时前
运维救火实战:钉钉API变更致薪资计算中断,如何用可视化逻辑引擎5分钟热修复
java·开源·全栈