java qps 怎么计算_一种高效的QPS统计方法 - 日理万妓 2022-11-04 00:51 582阅读 0赞 importjava.io.Serializable;importjava.util.ArrayList;importjava.util.Collections;importjava.util.HashMap;importjava.util.LinkedHashMap;importjava.util.List;importjava.util.Map;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.atomic.LongAdder;importjava.util.concurrent.locks.ReentrantLock;/\*\*\* @Author: gxj\*/ public classQPSCalculator \{privateRollingNumber rollingNumber;publicQPSCalculator() \{this.rollingNumber = newRollingNumber(); \}public voidpass() \{ rollingNumber.record(); \}private static final classRollingNumber \{/\*\*\* 槽位的数量\*/ private intsizeOfBuckets;/\*\*\* 时间片,单位毫秒\*/ private intunitOfTimeSlice;/\*\*\* 用于判断是否可跳过锁争抢\*/ private inttimeSliceUsedToCheckIfPossibleToBypass;/\*\*\* 槽位\*/ privateBucket\[\] buckets;/\*\*\* 目标槽位的位置\*/ private volatileInteger targetBucketPosition;/\*\*\* 接近目标槽位最新更新时间的时间\*/ private volatileLong latestPassedTimeCloseToTargetBucket;/\*\*\* 进入下一个槽位时使用的锁\*/ privateReentrantLock enterNextBucketLock;/\*\*\* 默认60个槽位,槽位的时间片为1000毫秒\*/ publicRollingNumber() \{this(60, 1000); \}/\*\*\* 初始化Bucket数量与每个Bucket的时间片等 \* \*@paramsizeOfBuckets \*@paramunitOfTimeSlice\*/ public RollingNumber(int sizeOfBuckets, intunitOfTimeSlice) \{this.latestPassedTimeCloseToTargetBucket = System.currentTimeMillis() - (2 \*unitOfTimeSlice);this.targetBucketPosition = null;this.sizeOfBuckets =sizeOfBuckets;this.unitOfTimeSlice =unitOfTimeSlice;this.enterNextBucketLock = newReentrantLock();this.buckets = newBucket\[sizeOfBuckets\];this.timeSliceUsedToCheckIfPossibleToBypass = 3 \*unitOfTimeSlice;for (int i = 0; i < sizeOfBuckets; i++) \{this.buckets\[i\] = newBucket(); \} \}private voidrecord() \{long passTime =System.currentTimeMillis();if (targetBucketPosition == null) \{ targetBucketPosition= (int) (passTime / unitOfTimeSlice) %sizeOfBuckets; \} Bucket currentBucket=buckets\[targetBucketPosition\];if (passTime - latestPassedTimeCloseToTargetBucket >=unitOfTimeSlice) \{if (enterNextBucketLock.isLocked() && (passTime - latestPassedTimeCloseToTargetBucket) \}else\{try\{ enterNextBucketLock.lock();if (passTime - latestPassedTimeCloseToTargetBucket >=unitOfTimeSlice) \{int nextTargetBucketPosition = (int) (passTime / unitOfTimeSlice) %sizeOfBuckets; Bucket nextBucket=buckets\[nextTargetBucketPosition\];if(nextBucket.equals(currentBucket)) \{if (passTime - latestPassedTimeCloseToTargetBucket >=unitOfTimeSlice) \{ latestPassedTimeCloseToTargetBucket=passTime; \} \}else\{ nextBucket.reset(passTime); targetBucketPosition=nextTargetBucketPosition; latestPassedTimeCloseToTargetBucket=passTime; \} nextBucket.pass();return; \}else\{ currentBucket=buckets\[targetBucketPosition\]; \} \}finally\{ enterNextBucketLock.unlock(); \} \} \} currentBucket.pass(); \}publicBucket\[\] getBuckets() \{returnbuckets; \} \}private static class Bucket implementsSerializable \{private static final long serialVersionUID = -9085720164508215774L;privateLong latestPassedTime;privateLongAdder longAdder;publicBucket() \{this.latestPassedTime =System.currentTimeMillis();this.longAdder = newLongAdder(); \}public voidpass() \{ longAdder.add(1); \}public longcountTotalPassed() \{returnlongAdder.sum(); \}public longgetLatestPassedTime() \{returnlatestPassedTime; \}public void reset(longlatestPassedTime) \{this.longAdder.reset();this.latestPassedTime =latestPassedTime; \} \}public static voidmain(String\[\] args) \{try\{final QPSCalculator qpsCalculator = newQPSCalculator();int threadNum = 4; CountDownLatch countDownLatch= newCountDownLatch(threadNum); List threadList = new ArrayList();for (int i = 0; i < threadNum; i++) \{ threadList.add(newThread() \{public voidrun() \{for (int i = 0; i < 50000000; i++) \{ qpsCalculator.pass(); \} countDownLatch.countDown(); \} \}); \}long startTime =System.currentTimeMillis();for(Thread thread : threadList) \{ thread.start(); \} countDownLatch.await();long endTime =System.currentTimeMillis();long totalTime = endTime -startTime; System.out.print("totalMilliseconds: " +totalTime); TimeUnit.SECONDS.sleep(1000L); \}catch(Exception e) \{ e.printStackTrace(); \} \} \}
还没有评论,来说两句吧...