spring 调用性能监控

不少时候, 当后端服务出现性能问题, 如何调优是个难题, 由于当业务变得很复杂, 定位问题十分困难.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