<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
依照領導要求區分了兩種壓測模式:固定次數壓測和固定時間壓測。此前一直沿用的都是固定次數,所以本次第二版剝離了固定次數的模式增加了固定時間的模式。
這是第一版:效能測試框架
package com.fun.base.constaint; import com.fun.frame.SourceCode; import java.util.concurrent.CountDownLatch; /** * 多執行緒任務基礎類別,可單獨使用 */ public abstract class ThreadBase<T> extends SourceCode implements Runnable { /** * 計數鎖 * <p> * 會在concurrent類裡面根據執行緒數自動設定 * </p> */ CountDownLatch countDownLatch; /** * 用於設定存取資源 */ public T t; protected ThreadBase() { super(); } /** * groovy無法直接存取t,所以寫了這個方法 * * @return */ public String getT() { return t.toString(); } /** * 執行待測方法的之前的準備 */ protected abstract void before(); /** * 待測方法 * * @throws Exception */ protected abstract void doing() throws Exception; /** * 執行待測方法後的處理 */ protected abstract void after(); public void setCountDownLatch(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } }
package com.fun.base.constaint; import com.fun.frame.excute.Concurrent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import static com.fun.utils.Time.getTimeStamp; /** * 請求時間限制的多執行緒類,限制每個執行緒執行的次數 * * <p> * 通常在測試某項用例固定時間的場景下使用,可以提前終止測試用例 * </p> * * @param <T> 閉包引數傳遞使用,Groovy指令碼會有一些相容問題,部分物件需要tostring獲取引數值 */ public abstract class ThreadLimitTimes<T> extends ThreadBase { private static final Logger logger = LoggerFactory.getLogger(ThreadLimitTimes.class); /** * 任務請求執行次數 */ public int times; /** * 用於設定存取資源 */ public T t; public ThreadLimitTimes(T t, int times) { this(times); this.t = t; } public ThreadLimitTimes(int times) { this(); this.times = times; } protected ThreadLimitTimes() { super(); } /** * groovy無法直接存取t,所以寫了這個方法 * * @return */ public String getT() { return t.toString(); } @Override public void run() { try { before(); List<Long> t = new ArrayList<>(); long ss = getTimeStamp(); for (int i = 0; i < times; i++) { long s = getTimeStamp(); doing(); long e = getTimeStamp(); t.add(e - s); } long ee = getTimeStamp(); logger.info("執行次數:{},總耗時:{}", times, ee - ss); Concurrent.allTimes.addAll(t); } catch (Exception e) { logger.warn("執行任務失敗!", e); } finally { if (countDownLatch != null) countDownLatch.countDown(); after(); } } /** * 執行待測方法的之前的準備 */ protected abstract void before(); /** * 待測方法 * * @throws Exception */ protected abstract void doing() throws Exception; /** * 執行待測方法後的處理 */ protected abstract void after(); }
package com.fun.base.constaint; import com.fun.frame.excute.Concurrent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import static com.fun.utils.Time.getTimeStamp; /** * 請求時間限制的多執行緒類,限制每個執行緒執行的時間 * <p> * 通常在測試某項用例固定時間的場景下使用,可以提前終止測試用例 * </p> * * @param <T> 閉包引數傳遞使用,Groovy指令碼會有一些相容問題,部分物件需要tostring獲取引數值 */ public abstract class ThreadLimitTime<T> extends ThreadBase { /** * 全域性的時間終止開關 */ private static boolean key = false; private static final Logger logger = LoggerFactory.getLogger(ThreadLimitTime.class); /** * 任務請求執行時間,單位是秒 */ public int time; /** * 用於設定存取資源 */ public T t; public ThreadLimitTime(T t, int time) { this(time); this.t = t; } public ThreadLimitTime(int time) { this(); this.time = time * 1000; } protected ThreadLimitTime() { super(); } @Override public void run() { try { before(); List<Long> t = new ArrayList<>(); long ss = getTimeStamp(); while (true) { long s = getTimeStamp(); doing(); long e = getTimeStamp(); t.add(e - s); if ((e - ss) > time || key) break; } long ee = getTimeStamp(); logger.info("執行時間:{} s,總耗時:{}", time / 1000, ee - ss); Concurrent.allTimes.addAll(t); } catch (Exception e) { logger.warn("執行任務失敗!", e); } finally { if (countDownLatch != null) countDownLatch.countDown(); after(); } } /** * 用於在某些情況下提前終止測試 */ public static void stopAllThread() { key = true; } }
這裡我多加了一個終止測試的key,暫時沒有用,以防萬一。之所以沒有采用另起執行緒去計時原因有二:進行測試過程中無論如何都會記錄時間戳,多餘的計算比較時間戳大小消耗效能很低,可以忽略;另起執行緒設計麻煩,在發生意外情況時缺少第二種保險措施。
下面是兩種實現類的Demo,以HTTPrequestbase作為基礎的多執行緒類。
/** * http請求多執行緒類 */ public class RequestThreadTimes extends ThreadLimitTimes { static Logger logger = LoggerFactory.getLogger(RequestThreadTimes.class); /** * 請求 */ public HttpRequestBase request; /** * 單請求多執行緒多次任務構造方法 * * @param request 被執行的請求 * @param times 每個執行緒執行的次數 */ public RequestThreadTimes(HttpRequestBase request, int times) { this.request = request; this.times = times; } @Override public void before() { GCThread.starts(); } @Override protected void doing() throws Exception { getResponse(request); } @Override protected void after() { GCThread.stop(); } /** * 多次執行某個請求,但是不記錄紀錄檔,記錄方法用 loglong * <p>此方法只適應與單個請求的重複請求,對於有業務聯絡的請求暫時不能適配</p> * * @param request 請求 * @throws IOException */ void getResponse(HttpRequestBase request) throws IOException { CloseableHttpResponse response = ClientManage.httpsClient.execute(request); String content = FanLibrary.getContent(response); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) logger.warn("響應狀態碼:{},響應內容:{}", content, response.getStatusLine()); response.close(); } }
package com.fun.frame.thead; import com.fun.base.constaint.ThreadLimitTime; import com.fun.frame.httpclient.ClientManage; import com.fun.frame.httpclient.FanLibrary; import com.fun.frame.httpclient.GCThread; import org.apache.http.HttpStatus; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpRequestBase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; /** * http請求多執行緒類 */ public class RequestThreadTime extends ThreadLimitTime { static Logger logger = LoggerFactory.getLogger(RequestThreadTime.class); /** * 請求 */ public HttpRequestBase request; /** * 單請求多執行緒多次任務構造方法 * * @param request 被執行的請求 * @param times 每個執行緒執行的次數 */ public RequestThreadTime(HttpRequestBase request, int time) { this.request = request; this.time = time; } @Override public void before() { GCThread.starts(); } @Override protected void doing() throws Exception { getResponse(request); } @Override protected void after() { GCThread.stop(); } /** * 多次執行某個請求,但是不記錄紀錄檔,記錄方法用 loglong * <p>此方法只適應與單個請求的重複請求,對於有業務聯絡的請求暫時不能適配</p> * * @param request 請求 * @throws IOException */ void getResponse(HttpRequestBase request) throws IOException { CloseableHttpResponse response = ClientManage.httpsClient.execute(request); String content = FanLibrary.getContent(response); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) logger.warn("響應狀態碼:{},響應內容:{}", content, response.getStatusLine()); response.close(); } }
其中可以發現,差別就在於屬性time還是times的設定。
package com.fun; import com.fun.base.constaint.ThreadLimitTime; import com.fun.frame.SourceCode; import com.fun.frame.excute.Concurrent; import java.util.ArrayList; import java.util.List; public class AR extends SourceCode { public static void main(String[] args) { ThreadLimitTime<Object> threadLimitTime = new ThreadLimitTime<Object>(10) { /** * 執行待測方法的之前的準備 */ @Override protected void before() { } /** * 待測方法 * * @throws Exception */ @Override protected void doing() throws Exception { AR.test(); } /** * 執行待測方法後的處理 */ @Override protected void after() { } }; new Concurrent(threadLimitTime,5).start(); FanLibrary.testOver(); } public static void test() { synchronized (AR.class) { sleep(100); output("fun"); } } }
剩下的mysql和redis以及dubbo的Demo就不寫了,各位看官看著發揮即可,更多關於java效能測試框架的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45