SPRING INTERCEPTORモニタJMS送信受付性能


spring aspectjとjmsを統合し、spring interceptorでjms送信受信方法を監視します.メソッド注釈タグの合計実行回数により、ブロッカーは、指定したメソッドがターゲット実行回数に実行された後、パフォーマンス追跡情報をログに記録します.
    
aop-conf.xml

  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
				http://www.springframework.org/schema/beans/spring-beans.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
     			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
				http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.2.xsd
				http://www.springframework.org/schema/cache
				http://www.springframework.org/schema/cache/spring-cache.xsd">
				
	<bean id="jmsMessageHanderMonitor"
		class="com.cn.ld.modules.jms.monitor.JmsMessageHanderMonitor">
		<property name="useDynamicLogger" value="false" />
		<constructor-arg index="0">
			<value>1</value>
		</constructor-arg>
	</bean>

	<aop:config>
		<aop:pointcut id="allServiceMethods"
			expression="execution(* com.cn.ld.modules.jms.worker..*(..))" />
		<aop:advisor pointcut-ref="allServiceMethods" advice-ref="jmsMessageHanderMonitor"
			order="2" />
	</aop:config>
</beans>
 

log4j.propertiesモニタinterceptor raceログ機能をオンにする

log4j.logger.com.cn.ld.modules.jms.monitor.JmsMessageHanderMonitor=TRACE

applicationContext.xml

<!-- aop source -->
	<import resource="aop-config.xml" />
 

MethodMonitorCount注記インタフェース

package com.cn.ld.modules.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodMonitorCount {
    int value() default 1;
}


JmsMessageHanderMonitor性能監視のaspect


package com.cn.ld.modules.jms.monitor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.concurrent.ConcurrentHashMap;

import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.aop.interceptor.AbstractMonitoringInterceptor;
import org.springframework.util.StopWatch;

import com.cn.ld.modules.annotation.MethodMonitorCount;

public class JmsMessageHanderMonitor extends AbstractMonitoringInterceptor {

	private static final long serialVersionUID = 1L;
	private ConcurrentHashMap<java.lang.reflect.Method, PerformanceSampl> methodPerfSampl = new ConcurrentHashMap<java.lang.reflect.Method, PerformanceSampl>();

	private int monitorCount = 1;

	public JmsMessageHanderMonitor(int monitorCount) {
		this.monitorCount = monitorCount;
	}

	public JmsMessageHanderMonitor(boolean useDynamicLogger) {
		setUseDynamicLogger(useDynamicLogger);
	}

	@Override
	protected Object invokeUnderTrace(MethodInvocation methodinvocation,
			Log logger) throws Throwable {
		ReflectiveMethodInvocation reflectMethod = (ReflectiveMethodInvocation) methodinvocation;
		Method m = reflectMethod.getMethod();
		Annotation[] annotations = m.getAnnotations();

		if (null == annotations || annotations.length == 0) {
			return methodinvocation.proceed();
		}

		PerformanceSampl sampl = null;
		//           key  ,      ,              PerformanceSampl
		if (methodPerfSampl.containsKey(m)) {
			sampl = methodPerfSampl.get(m);
		} else {
			sampl = new PerformanceSampl();
			methodPerfSampl.put(m, sampl);
		}
		String target = m.toString();
		//         ,       
		if (sampl.getReceNo() == 0) {

			StopWatch sw = new StopWatch(target);
			sampl.setStopWatch(sw);
			MethodMonitorCount mmc = (MethodMonitorCount) annotations[0];
			sampl.setMaxReceNo(mmc.value());
			sw.start(m.getName());
		}

		//       
		Object obj = methodinvocation.proceed();

		//           
		sampl.setReceNo(sampl.getReceNo() + 1);

		//                    ,            
		if (sampl.getReceNo() == sampl.getMaxReceNo()) {
			sampl.getStopWatch().stop();

			//     
			showTraceInfo(logger, sampl, target);

			//     ,     cache    
			methodPerfSampl.remove(m);
		}

		return obj;
	}

	private void showTraceInfo(Log logger, PerformanceSampl sampl, String target) {
		String formatStr = "monitor target method:{0} ; expect execute times:{1};actual execute times:{2};execution Speed:{3}/s";
		MessageFormat paramMf = new MessageFormat(formatStr);
		long costTime = (sampl.getStopWatch().getTotalTimeMillis() / 1000);
		int executeTimes = sampl.getReceNo();
		costTime = costTime == 0 ? costTime : (executeTimes / costTime);
		logger.trace(paramMf.format(new Object[] { target,
				sampl.getMaxReceNo(), executeTimes, costTime }));
	}
         /*
          *    
          */
	private static class PerformanceSampl {
		private StopWatch stopWatch;
		private int maxReceNo;
		//     
		private int receNo;

		public void setReceNo(int receNo) {
			this.receNo = receNo;
		}

		public StopWatch getStopWatch() {
			return stopWatch;
		}

		public void setStopWatch(StopWatch stopWatch) {
			this.stopWatch = stopWatch;
		}

		public int getMaxReceNo() {
			return maxReceNo;
		}

		public void setMaxReceNo(int maxReceNo) {
			this.maxReceNo = maxReceNo;
		}

		public int getReceNo() {
			return receNo;
		}

	}

	public int getMonitorCount() {
		return monitorCount;
	}

	public void setMonitorCount(int monitorCount) {
		this.monitorCount = monitorCount;
	}
}


コンソール情報は以下の通りです

[2013-07-18 17:12:00,645][TRACE]<main>(JmsMessageHanderMonitor.java:87) - monitor target method:public void com.cn.ld.modules.jms.worker.JmsSender.sendSingle(java.lang.String,javax.jms.Destination) ; expect execute times:10,000;actual execute times:10,000;execution Speed:10,000/s
[2013-07-18 17:12:00,784][TRACE]<jmsContainer-1>(JmsMessageHanderMonitor.java:87) - monitor target method:public abstract void com.cn.ld.modules.jms.handler.MessageHandler.handleMessage(java.lang.String) ; expect execute times:10,000;actual execute times:10,000;execution Speed:10,000/s