问题描述
昨天产品反馈数据统计有问题。经过初步排查,发现这个审批流程的代码只执行了一半,并且方法没有加事物,所以执行到中途如果报错,产生的数据刚好和线上问题对上。但是抓了日志,却没有报错日志。没加事务、没有忽略大小写、抛出异常却没日志,三个问题同时存在,让我排查了一天才确认引起脏数据的问题。
原因分析:
定位代码问题 :经过一天的反复排查、确认、本地复现,咱终于找到原因了,引起数据问题的原因是方法没加事物,在校验身份证是否相等时没有忽略大小写,造成身份证号在equals比较的时候结果为false会抛出异常,但是
拉了生产环境的日志,没有出现任何报错。
确认报错日志是被吞掉了 :看到这儿其实已经知道了,定位这个问题的难点其实是报错日志被吞掉了。为了确认这个问题,我在代码中间抛出了一个RuntimeException发现控制台也确实没有打印日志,我把Logback删掉之后还是报错,看了一下代码也没有全局捕获异常的地方,但是接口返回的错误信息,明显是被处理之后的。到这儿我大概猜到问题了,因为这个接口是dubbo
代理的接口,确实是呀,这个地方的异常被捕获
了。 com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker
java
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
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执行流程的分析分章