Java计算当前应用的tps_Java TPS实现

本文介绍了如何使用Java并发包中的工具实现一个TPS(每秒事务处理量)性能测试工具,特别关注了如何测试OKHttp库执行HTTP请求的性能。通过结合使用ExecutorService、CountDownLatch、CyclicBarrier和原子类等并发组件,创建了一个多线程测试环境。在30秒内,5个线程执行HTTP请求,最终得出TPS结果。
摘要由CSDN通过智能技术生成

写在前面TPS即每秒查询事物,可以用于测试一个方法、工具或者系统的性能。本文采用Java并发包中的工具实现了一个工具TPS性能测试。主要是测试OKHttp库来执行Http请求的性能。测试代码用到了Java了线程池ExecuterService,CountDownLatch, CyclicBarrier, 原子类,volatile关键词等。可算是对Java并发组件的组合使用。下面直接贴出源码,仅供参考,如有错误,欢迎指出,以期共同探讨。

TPS 实现源码package cn.concurrent;

import java.math.RoundingMode;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.atomic.AtomicLong;

import util.OkHttpUtil;

import com.google.common.math.LongMath;

/**

* 每秒事物执行次数统计

*

* @author Xie le

* @date 2016/7/9

*/

public class TpsWorkbeanch {

/** 线程数量 */

public static final int N_THRESHOLDS = 5;

/** 30 秒总时间 */

public static final int TIME_THRESHOLDS = 30;

/** 用原子变量来统计执行时间,便于作原子递减 */

private static AtomicInteger totalTime = new AtomicInteger(TIME_THRESHOLDS);

/** 用于统计执行的事物总数,用原子方式累加记录 */

private static AtomicLong totalExecCount = new AtomicLong(0L);

/** 需要到等到所有线程都在同一起跑线,才开始统计计数,类似于发令枪 */

private static CyclicBarrier barrier = new CyclicBarrier(N_THRESHOLDS);

/** 执行时间到达时,所有的线程需要依次退出,主线程才开始统计执行事物总数 */

private static CountDownLatch countDownLatch = new CountDownLatch(N_THRESHOLDS);

/** 线程执行标记 , 用volatile修饰,使变量修改具有线程可见性 */

private static volatile boolean runnning = true;

/** 用线程池来执行统计 */

private static ExecutorService executorService;

/**

* 用接口来作模拟统计

*/

interface Job {

void execute() throws Exception;

}

/**

* 具体Job,模拟完成一次Http请求 BTW:内部类用static修饰

*/

static class JobDetail implements Job {

public void execute() throws Exception {

String run = OkHttpUtil.run("http://publicobject.com/helloworld.txt");

}

}

/**

* Worker执行Job

*/

static class Worker implements Runnable {

private Job job;

Worker(Job job) {

this.job = job;

}

// 每个线程执行的事物统计量

int innerCount = 0;

public void run() {

try {

barrier.await(); // 等到所有线程都在起跑线

while (runnning) {

this.job.execute();

innerCount++;

}

} catch (Exception e) {

System.out.println("线程Id:" + Thread.currentThread().getId() + " " + e.getMessage());

} finally {

// 累加到总记录统计量

System.out.println("线程Id:" + Thread.currentThread().getId() + " 执行事物次数为:" + innerCount);

totalExecCount.getAndAdd(innerCount);

// 线程结束后,依次计数, 便于主线程继续执行

countDownLatch.countDown();

}

}

}

public static void run() throws Exception {

Job job = new JobDetail(); // 创建Job

executorService = Executors.newFixedThreadPool(N_THRESHOLDS); // 新建固定大小线程的池子

for (int i = 0; i < N_THRESHOLDS; i++) {

executorService.submit(new Worker(job)); // 提交线程到池子中

}

// 还需要一个线程,用于周期检查执行时间是否到达

final ScheduledExecutorService scheduledExcutor = Executors.newSingleThreadScheduledExecutor();

scheduledExcutor.scheduleAtFixedRate(new Runnable() {

public void run() {

if (totalTime.decrementAndGet() == 0) { // 执行时间递减到0

runnning = false; // 告诉线程,时间到了,所有线程不再执行

scheduledExcutor.shutdownNow();

}

}

}, 1L, 1L, TimeUnit.SECONDS);

// 主线程等到所有的线程都退出,则开始统计

countDownLatch.await();

long totalExeCount = totalExecCount.get();

System.out.println(N_THRESHOLDS + " 个线程," + TIME_THRESHOLDS + " 秒内总共执行的事物数量:" + totalExeCount);

long tps = LongMath.divide(totalExeCount, TIME_THRESHOLDS, RoundingMode.HALF_EVEN);

System.out.println("OKHttp执行的TPS: " + tps);

executorService.shutdownNow(); // 关闭线程池

}

public static void main(String[] args) throws Exception {

run();

}

}

其中用到的OKHttp类如下:

package util;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

/**

* OkHttp工具

* @author Xie le

* @date 2016/6/30

*/

public class OkHttpUtil {

private static OkHttpClient okHttpclient = null;

static {

okHttpclient = new OkHttpClient.Builder()

.connectTimeout(3, TimeUnit.SECONDS)

.build();

}

public static String run(String url) throws Exception {

Request request = new Request.Builder().url(url).build();

Response response = okHttpclient.newCall(request).execute();

if (!response.isSuccessful()) {

throw new IOException("Unexpected code " + response);

}

return response.body().string();

}

}

测试结果测试结果与环境有关。以我本机为例,5个线程,30秒内的测试结果如下:

线程Id:14 connect timed out

线程Id:14 执行事物次数为:0

线程Id:10 connect timed out

线程Id:10 执行事物次数为:0

线程Id:11 执行事物次数为:29

线程Id:13 执行事物次数为:33

线程Id:12 执行事物次数为:26

5 个线程,30 秒内总共执行的事物数量:88

OKHttp执行的TPS: 3

最后直接阅读代码,可以掌握Java并发的常用的工具类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值