不少时候, 当后端服务出现性能问题, 如何调优是个难题, 由于当业务变得很复杂, 定位问题十分困难.java
企业开发中经常使用的spring构架提供了一个很好的机制 AOP, 方便咱们快速定位问题.spring
这里演示一个组件, 利用AOP, 打印出 spring 调用栈耗时.后端
@Component("performanceInspector") public class PerformanceInspector { private static class InvokeInfo { List<MutableTriple<Integer, MethodSignature, Long>> infos = new ArrayList<>(); int currentLevel; } private static final ThreadLocal<InvokeInfo> invokeInfoThreadLocal = new InheritableThreadLocal<>(); public Object inspect(final ProceedingJoinPoint pjp) throws Throwable { MethodSignature signature = (MethodSignature) pjp.getSignature(); InvokeInfo invokeInfo = invokeInfoThreadLocal.get(); boolean isRoot = false; if (invokeInfo == null) { invokeInfo = new InvokeInfo(); invokeInfoThreadLocal.set(invokeInfo); isRoot = true; } MutableTriple<Integer, MethodSignature, Long> currInvokeInfo = MutableTriple.of(invokeInfo.currentLevel++, signature, 0L); invokeInfo.infos.add(currInvokeInfo); try { Tick tick = Tick.tick(); Object result = pjp.proceed(); currInvokeInfo.setRight(tick.nip()); return result; } finally { invokeInfo.currentLevel--; if (isRoot) { for (MutableTriple<Integer, MethodSignature, Long> info : invokeInfo.infos) { System.out.println(genInfoStr(info)); } invokeInfoThreadLocal.set(null); } } } private String genInfoStr(MutableTriple<Integer, MethodSignature, Long> info) { return Strings.repeat("\t", info.getLeft()) + info.getMiddle().getDeclaringType().getSimpleName() + "." + info.getMiddle().getName() + " :" + info.getRight() + "ms"; } }
配置一下AOP:性能
<aop:config> <aop:aspect ref="performanceInspector" > <aop:around method="inspect" pointcut="execution(* *(..))"/> </aop:aspect> </aop:config>
测试用例测试
@Component("PerformanceInspectorTest") public class PerformanceInspectorTest { @Resource(name = "PerformanceInspectorTest") PerformanceInspectorTest self; @Test public void test() { self.f(); } public void f() { self.a(); self.b(); self.c(); } public void a() { self.b(); } public void b() { self.c(); } public void c() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
输出结果code
PerformanceInspectorTest.f :306ms PerformanceInspectorTest.a :99ms PerformanceInspectorTest.b :99ms PerformanceInspectorTest.c :99ms PerformanceInspectorTest.b :99ms PerformanceInspectorTest.c :99ms PerformanceInspectorTest.c :99ms