排查项目中的循环调用

项目优化系列

循环调用排查【for循环数据库调用,dubbo调用】

在企业级开发中,由于项目会经过很多开发,开发的规范参差不齐,导致出现很多for循环调用数据库,for循环调用dubbo接口,导致明明能够只需要一次调用就能解决的问题,往往反而需要多次调用,从来带来了各种系统资源紧张。

解决思路一:人肉排查
缺点:效率低下,覆盖不全面容易遗漏。

解决思路二:通过 调用链路+traceId 持久化调用信息 依次排查出在同一时间内相同traceId多次调用发现问题
dubbo实现
使用filter扩展实现,在META-INF目录下配置过滤器

recursiveCallFilter=com.xxx.xxx.xxx.config.RecursiveCallFilter
@Activate(group = {"consumer"})
public class RecursiveCallFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RecursiveCallFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        if (stack.length > 0) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < stack.length; i++) {
            	//使用项目包名前缀去除非业务调用
                if(stack[i].getClassName().startsWith("com.xxx.xxx.xxx")){
                    sb.append(stack[i].getClassName()+"*"+stack[i].getMethodName()+"@");
                }
            }
            logger.info("RecursiveCallFilter.invoke.trace_id:{},stack:{}", TraceIdUtil.getCurrentTraceId(),sb.toString());
        }
        //自行实现持久化方式
        return invoker.invoke(invocation);
    }
}

数据库实现

@Component
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class RecursiveCallInterceptor implements Interceptor {
    private static final Logger logger = LoggerFactory.getLogger(RecursiveCallInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        if (stack.length > 0) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < stack.length; i++) {
                if (stack[i].getClassName().startsWith("com.xx.xx.xx")) {
                    sb.append(stack[i].getClassName() + "*" + stack[i].getMethodName() + "@");
                }
            }
            logger.info("RecursiveCallInterceptor.invoke.trace_id:{},stack:{}", TraceIdUtil.getCurrentTraceId(),
                sb.toString());
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值