likes
comments
collection
share

【因为异常被吞掉,我排查了一天才确认问题】

作者站长头像
站长
· 阅读数 3

问题描述

昨天产品反馈数据统计有问题。经过初步排查,发现这个审批流程的代码只执行了一半,并且方法没有加事物,所以执行到中途如果报错,产生的数据刚好和线上问题对上。但是抓了日志,却没有报错日志。没加事务、没有忽略大小写、抛出异常却没日志,三个问题同时存在,让我排查了一天才确认引起脏数据的问题。

原因分析:

定位代码问题:经过一天的反复排查、确认、本地复现,咱终于找到原因了,引起数据问题的原因是方法没加事物,在校验身份证是否相等时没有忽略大小写,造成身份证号在equals比较的时候结果为false会抛出异常,但是拉了生产环境的日志,没有出现任何报错。

确认报错日志是被吞掉了:看到这儿其实已经知道了,定位这个问题的难点其实是报错日志被吞掉了。为了确认这个问题,我在代码中间抛出了一个RuntimeException发现控制台也确实没有打印日志,我把Logback删掉之后还是报错,看了一下代码也没有全局捕获异常的地方,但是接口返回的错误信息,明显是被处理之后的。到这儿我大概猜到问题了,因为这个接口是dubbo代理的接口,确实是呀,这个地方的异常被捕获了。 com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker

  public Result invoke(Invocation invocation) throws RpcException {
        try {
            return new RpcResult(doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()));
        } catch (InvocationTargetException e) {
        	//打断点走的这儿
            return new RpcResult(e.getTargetException());
        } catch (Throwable e) {
            throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

根本原因:在我debug dubbo源码的时候发现,其实是走了以下ExceptionFilter的代码的,至少下面的logger是执行了的,但是控制台也没有输出日志。 【因为异常被吞掉,我排查了一天才确认问题】 说明dubbo没有打印日志的根本原因是因为日志依赖存在问题,并且控制台启动的时候有一个日志警告如下:

log4j:WARN No appenders could be found for logger (com.alibaba.dubbo.common.logger.LoggerFactory). log4j:WARN Please initialize the log4j system properly. log4j:WARN See logging.apache.org/log4j/1.2/f… for more info.


解决方案:

1.启动类上增加以下代码日志问题就解决了(虽然我们的服务实现类的日志被吃掉了,但是我们消费者端的日志是会打印,所以以后看日志还得多留点心眼呀。)

Logger root = Logger.getRootLogger(); root.addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));

eg:

java
	public static void main(String[] args) {
		Logger root = Logger.getRootLogger();
    	root.addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));
		TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
		new SpringApplication(CustomerServiceApplication.class).run(args);
	}

2.方法上增加事务注解、equals比较身份证的时候忽略大小写(数据库设置的编码集是忽略了大小写的哦)。

从排查问题到解决问题看出了我对dubbo框架、和日志框架其实是不懂原理的,所以排查问题花了比较多的时间,后面会出一个日志系统,dubbo执行流程的分析分章