并发性能计数器模块

请先阅读  REFER:  http://blog.csdn.net/tenebaul/article/details/17144059

涉及的类: ConcurrentPerformanceBenchmarkFactory.java  ConcurrentPerformanceBenchmark.java和ConcurrentPerformanceBenchmarkMBean.java 和 JmxMBeanManager.java

 

public interface ConcurrentPerformanceBenchmarkMBean {

    public String getName();

    /** 执行的开始时间 yyyy-MM-dd HH:mm:ss*/
    public String getInitActionTime();

    /** 执行的结束时间 yyyy-MM-dd HH:mm:ss */
    public String getLastActionTime();

    /** 总共处理了多少个 */
    public int getCountTotal();

    /** 模拟引擎平均时延 */
    public double getLatencyAvgMS();

    /** 模拟引擎吞吐量*/
    public int getThroughputQPS();

    /**
     * 模拟引擎平均时延的倒数,只是为给平均时延代表的数量级变换成处理能力。
     * getThroughputQPS()与getLatencyFlipQPS()的差距体现的是并发带来的好处。
     * */
    public int getLatencyFlipQPS();
}


 

import java.sql.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import com.sohu.video.ad.adfront.util.DateUtil;

/** 性能测试 */
public class ConcurrentPerformanceBenchmark implements ConcurrentPerformanceBenchmarkMBean {

    private final AtomicInteger totalCount = new AtomicInteger(0);
    private final AtomicLong totalLatency = new AtomicLong(0);

    private final String name;

    public ConcurrentPerformanceBenchmark(String name) {
        super();
        this.name = name;
        JmxMBeanManager.getInstance().appendMBean(this, name);
    }

    public void benchmarkAction(int actionIncrValue, long actionStartTime, long actionEndedTime) {
        initIfAbsent(actionStartTime);
        lastEndedTime(actionEndedTime);
        incrCountAndLatency(actionIncrValue, actionEndedTime-actionStartTime);
    }

    private volatile long initActionStartTime = 0;//只写一次
    private final AtomicLong lastActionEndedTime = new AtomicLong();

    protected void initIfAbsent(long initExecTime) {
        if (initActionStartTime <= 0) {
            initActionStartTime = initExecTime;
        }
    }

    protected void lastEndedTime(long lastExecTime) {
        lastActionEndedTime.set(lastExecTime);
    }

    public void incrCountAndLatency(int incrValue, long timeCost) {
        totalCount.addAndGet(incrValue);
        totalLatency.addAndGet(timeCost);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getCountTotal() {
        return totalCount.get();
    }

    @Override
    public double getLatencyAvgMS() {
        int num = totalCount.get();
        if (num <=0) {
            return 0;
        }
        return (totalLatency.get()+0.0) / totalCount.get();
    }

    @Override
    public int getLatencyFlipQPS() {
        long time = totalLatency.get();
        if (time <=0) {
            return 0;
        }
        return (int) ((totalCount.get()/(totalLatency.get()+0.0))*1000);
    }


    @Override
    public String getInitActionTime() {
        if (initActionStartTime <= 0) {
            return "";
        }
        return DateUtil.format(new Date(initActionStartTime), "yyyy-MM-dd HH:mm:ss");
    }

    @Override
    public String getLastActionTime() {
        if (lastActionEndedTime.get() <= 0) {
            return "";
        }
        return DateUtil.format(new Date(lastActionEndedTime.get()), "yyyy-MM-dd HH:mm:ss");
    }


    @Override
    public int getThroughputQPS() {
        if (initActionStartTime <= 0 || lastActionEndedTime.get() <= 0) {
            return 0;
        }
        return (int) (totalCount.get() / ((lastActionEndedTime.get()-initActionStartTime) / 1000.0) );
    }

}


 

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

public class ConcurrentPerformanceBenchmarkFactory {

    private static final ConcurrentHashMap<String, ConcurrentPerformanceBenchmark> container = new ConcurrentHashMap<String, ConcurrentPerformanceBenchmark>();



    @SuppressWarnings("rawtypes")
    public static ConcurrentPerformanceBenchmark getBenchmark(Class className) {
        return getBenchmark(className, true);
    }

    @SuppressWarnings("rawtypes")
    public static ConcurrentPerformanceBenchmark getBenchmark(Class className, boolean bySimpleName) {
        return getBenchmark(bySimpleName ? className.getSimpleName() : className.getName());
    }

    public static ConcurrentPerformanceBenchmark getBenchmark(String name) {
        ConcurrentPerformanceBenchmark cpb = container.get(name);
        if (cpb != null) {
            return cpb;
        }
        /* ConcurrentPerformanceBenchmark 会加入JMX,属于昂贵对象,引入替身 */
        ReentrantLock stuntman = getStuntmanInstanceByName(name);
        try {
            stuntman.lock();
            cpb = container.get(name);
            if (cpb == null) {//Double-check
                ConcurrentPerformanceBenchmark cpbNew = new ConcurrentPerformanceBenchmark(name);
                ConcurrentPerformanceBenchmark cpbPre = container.putIfAbsent(name, cpbNew);
                if (cpbPre != null) {//不可能发生的,因为有锁
                    throw new IllegalStateException("Concurrent Error ConcurrentPerformanceBenchmark");
                } else {
                    cpb = cpbNew;
                }
            }
            return cpb;


        } finally {
            stuntman.unlock();
        }

    }

    private static final ConcurrentHashMap<String, ReentrantLock> stuntmanContainer = new ConcurrentHashMap<String,ReentrantLock>();
    private static ReentrantLock getStuntmanInstanceByName(String name) {
        ReentrantLock stuntman = stuntmanContainer.get(name);
        if (stuntman == null) {
            ReentrantLock newStuntman = new ReentrantLock();
            ReentrantLock preStuntman = stuntmanContainer.putIfAbsent(name, newStuntman);
            stuntman = (preStuntman!=null ? preStuntman : newStuntman);
        }
        return stuntman;
    }

}


 

import java.lang.management.ManagementFactory;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import javax.management.MBeanServer;
import javax.management.ObjectName;

public class JmxMBeanManager {
    private static final Object mbsCreateMonitor = new Object();
    private static JmxMBeanManager thisObj;

    private final MBeanServer mbs;

    public JmxMBeanManager() {
        mbs = ManagementFactory.getPlatformMBeanServer();
    }

    public static JmxMBeanManager getInstance() {
        synchronized (mbsCreateMonitor) {
            if (null == thisObj) {
                thisObj = new JmxMBeanManager();
            }
        }

        return thisObj;
    }

    public boolean isRegistered(String name) {
        try {
            ObjectName objName = new ObjectName(name);
            return mbs.isRegistered(objName);
        }
        catch (Exception e) {
            throw new RuntimeException("exception while checking if MBean is registered, " + name, e);
        }
    }


    /** 记录每个类产生的实例的个数 */
    @SuppressWarnings("rawtypes")
    private final ConcurrentHashMap<Class, AtomicInteger> classInstanceCounter = new ConcurrentHashMap<Class, AtomicInteger>();
    @SuppressWarnings("rawtypes")
    private int incrAndGet(Class Key) {
        return incrAndGet(Key, 1);
    }
    @SuppressWarnings("rawtypes")
    private int incrAndGet(Class key, final int incrValue) {
        AtomicInteger bookIdCount = classInstanceCounter.get(key);
        if (bookIdCount == null) {
            AtomicInteger bookIdPrev = classInstanceCounter.putIfAbsent(key, new AtomicInteger(incrValue));
            if (bookIdPrev != null) {
                return bookIdPrev.addAndGet(incrValue);
            } else {
                return incrValue;
            }
        } else {
            return bookIdCount.addAndGet(incrValue);
        }
    }

    public void appendMBean(Object theBean) {
        appendMBean(theBean, null, 5);
    }
    /**
     * @param   simpleName  NULL的时,系统自动提取类名简称。
     * */
    public void appendMBean(Object theBean, String simpleName) {
        if (simpleName == null || simpleName.length() > 15) {
            throw new IllegalArgumentException();
        }
        appendMBean(theBean,simpleName, -1);
    }


    public void appendMBean(Object theBean, String simpleName, int prefix) {
        String beanName = genBeanName(theBean, simpleName, prefix);
        if (JmxMBeanManager.getInstance().isRegistered(beanName)) {
            JmxMBeanManager.getInstance().unregisterMBean(beanName);
        }
        JmxMBeanManager.getInstance().registerMBean(theBean, beanName);
    }

    @SuppressWarnings("rawtypes")
    protected String genBeanName(Object theBean, String simpleName, int prefix) {
        Class beanClass = theBean.getClass();

        String prefixName = (prefix < 0 ? beanClass.getName() : packagePrefix(beanClass, prefix));
        String typeName = (simpleName==null ? beanClass.getSimpleName() : simpleName );

//      String prefixName = beanClass.getName();
//      String typeName = beanClass.getSimpleName();

        int instanceNum = incrAndGet(beanClass);

        String beanName = prefixName+":type="+typeName+ "-" + instanceNum;;
        return beanName;
    }

    private static String packagePrefix(String className, int maxDot) {
        int fromIndex = -1;
        int lastIndex = 0;
        int iteration = 0;
        do {
            lastIndex = fromIndex;
            fromIndex = className.indexOf(".", fromIndex+1);
            iteration ++;
        }  while (iteration < maxDot && fromIndex!=-1);

        if (lastIndex <= 0) {
            return className;
        }
        return className.substring(0,lastIndex);
    }

    @SuppressWarnings("rawtypes")
    private static String packagePrefix(Class classArg, int maxDot) {
        return packagePrefix(classArg.getName(), maxDot);
    }


    private void registerMBean(Object theBean, String name) {
        try {
            ObjectName objName = new ObjectName(name);
            mbs.registerMBean(theBean, objName);
        }
        catch (Exception e) {
            throw new RuntimeException("exception while registering MBean, " + name, e);
        }
    }

    private void unregisterMBean(String name) {
        try {
            ObjectName objName = new ObjectName(name);
            mbs.unregisterMBean(objName);
        }
        catch (Exception e) {
            throw new RuntimeException("exception while unregistering MBean, " + name, e);
        }
    }

    public Object getAttribute(String objName, String attrName) {
        try {
            ObjectName on = new ObjectName(objName);
            return mbs.getAttribute(on, attrName);
        }
        catch (Exception e) {
            throw new RuntimeException("exception while getting MBean attribute, " + objName + ", " + attrName, e);
        }
    }

    public Integer getIntAttribute(String objName, String attrName) {
        return (Integer) getAttribute(objName, attrName);
    }

    public String getStringAttribute(String objName, String attrName) {
        return (String) getAttribute(objName, attrName);
    }
}

 

使用DEMO:

ConcurrentPerformanceBenchmark benchmarkParse = ConcurrentPerformanceBenchmarkFactory.getBenchmark("RDBLoaderParse");
        ConcurrentPerformanceBenchmark benchmarkStore = ConcurrentPerformanceBenchmarkFactory.getBenchmark("RDBLoaderStore");
        try {
            Entry entry = rdb.next();

            while (entry != null) {
                long st = SystemClock.systemCurrentTimeMillis();
                if (entry.value != null) {//过滤机制的存在,可能VALUE为空
                    freqCtrl.set(entry.key, (ConcurrentHashMap<String,FreqCtrlPeriod>)entry.value);
                }
                long mt = SystemClock.systemCurrentTimeMillis();
                entry = rdb.next();
                long et = SystemClock.systemCurrentTimeMillis();

                benchmarkStore.benchmarkAction(1, st, mt);
                benchmarkParse.benchmarkAction(1, mt, et);
            }

        } finally {
            if ( rdb!= null) {
                rdb.close();
            }
            LOG.info("loaded rdb named {} in {}", rdbFile.getName(), Thread.currentThread().getName());
        }


 


JMX查看性能效果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值