可以监控方法的rt监控,日志会打印在service_stdout.log
https://www.jianshu.com/p/e5bba03fd64f
下面的例子是通过切面将方法耗时统计封装起来,便于能力复用,需要改能力的方法加上注解即可。
注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RtAnnotation {
}
切面
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.ExponentiallyDecayingReservoir;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
/**
* @author: <a></a>
* @date:
* @time:
* @description: 记录方法耗时的切面,方法耗时信息打印在service_stdout.log
*/
@Slf4j
@Aspect
@Component
public class RtAspect {
/**
* 统计rt的间隔,单位秒
*/
private static final long consoleReporterPeriod = 60L;
/**
* 度量类型 直方图:计算间隔内执行次数count、最小值min,最大值max,平均值mean,方差stddev,中位数median,75百分位, 90百分位, 95百分位, 98百分位, 99百分位, 和 99.9百分位的值
*/
private static final String metricType = "histogram";
private static final MetricRegistry registry = new MetricRegistry();
static {
// 通过Metric,每隔1分钟,统计一次方法调用的rt情况
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(consoleReporterPeriod, TimeUnit.SECONDS);
}
/**
* 记录标记注解RtAnnotation.class的方法的耗时,1分钟统计一次均值,避免实时日志太多,不方便全局观察rt
*
* @param joinPoint 切点
* @return 方法执行的结果
* @throws Throwable 异常
*/
@Around("execution(public * com.xxx.afc..*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 开始毫秒数
long start = System.currentTimeMillis();
Object object = joinPoint.proceed();
// 方法执行完毕的耗时
long cost = System.currentTimeMillis() - start;
// 如果方法没有标记RtAnnotation注解,直接返回
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
if (!methodSignature.getMethod().isAnnotationPresent(RtAnnotation.class)) {
return object;
}
// 统计方法执行耗时
// 签名=类名+方法名+histogram
String key = MetricRegistry.name(methodSignature.getMethod().getDeclaringClass().getSimpleName(),
methodSignature.getMethod().getName(),
metricType);
MetricFilter filter = (signature, metric) -> signature.equals(key) && metric instanceof Histogram;
SortedMap<String, Histogram> histogramSortedMap = registry.getHistograms(filter);
Histogram histogram = null;
if (MapUtils.isEmpty(histogramSortedMap)) {
histogram = new Histogram(new ExponentiallyDecayingReservoir());
registry.register(key, histogram);
} else {
histogram = histogramSortedMap.get(key);
}
histogram.update(cost);
return object;
}
}
效果打印: