Mybatis请求的性能指标收集——Prometheus

mybatis的性能指标统计与Http类似,也是基于aop的方式,利用mybatis提供的intercept机制。直接看下Interceptor的定义:

@Intercepts(
    value = {
        @Signature (type=Executor.class,
                method="update",
                args={MappedStatement.class,Object.class}),
        @Signature(type=Executor.class,
                method="query",
                args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class,
                        CacheKey.class,BoundSql.class}),
        @Signature(type=Executor.class,
                method="query",
                args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})
    }
)
public class MybatisProfilerPlugin implements Interceptor {
    private static final Stats MYBATIS_STAT = Profiler.Builder
            .builder()
            .type("mybatis")
            .build();

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

        if (!System.getProperty("mybatisProfileEnable", "true").equalsIgnoreCase("true")) {
            return invocation.proceed();
        }
        final Object[] args = invocation.getArgs();
        if (args != null && args.length > 0) {
            long begin = System.nanoTime();
            final MappedStatement mappedStatement = (MappedStatement) args[0];
            if (mappedStatement != null) {
                final String methodName = mappedStatement.getId(); //对应的是Mapper中的一个方法,如com.coohua.mapper.UserMapper.selectUser
                final String declaringTypeName = mappedStatement.getResource();  //对应的就是一个Mapper类文件,如UserMapper.java
                //以类名和方法名为标签
                String[] tags = new String[]{"operation", methodName, "class", declaringTypeName};
                try {
                    //每个请求gauge+1
                    MYBATIS_STAT.incConc(tags);
                    return invocation.proceed();
                } catch (Throwable throwable) {
                    //统计错误数
                    MYBATIS_STAT.error(tags);
                    throw throwable;
                } finally {
                    //请求结束gauge-1
                    MYBATIS_STAT.decConc(tags);
                    //统计请求执行时间
                    MYBATIS_STAT.observe(System.nanoTime() - begin, TimeUnit.NANOSECONDS, tags);
                }
            }
        }
        return invocation.proceed();
    }

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

    @Override
    public void setProperties(Properties properties) {

    }
}

在使用框架中注册好mybatis拦截器即可:

<plugins>
     <plugin interceptor="com.pepper.metrics.integration.mybatis.MybatisProfilerPlugin" />
</plugins>

指标收集结果:

 

posted @ 2021-02-08 15:05  jingyi_up  阅读(487)  评论(0编辑  收藏  举报