自己實現的附帶文件的壓力測試方法
前段時間做了一個服務器端接口,是附帶文件上傳的;后來我們要對這個接口進行壓力測試;
其實很多現成的方式可以做壓力測試,但是附帶文件的的壓力測試缺不怎么符合我的需求,jmeter是可以做附帶文件上傳的壓力測試的,只是它是圖形界面,而我目前的需求是要在測試機器上面去跑測試,而測試服務器是不能帶圖形界面的,所以jmeter的方案否決掉;
apache ab test,也是一個壓力測試的好工具,只是研究了好久老搞不掂怎么做附帶文件上傳的壓力測試(備注:在本文的最后我附帶一下我研究的結果,說多了都是淚)
好了,現在我說下我自己的這個測試工具:
它依賴于賴于httpclient相關的包,包括:commons-codec-1.6.jar、commons-logging-1.1.3.jar、fluent-hc-4.3.4.jar、httpclient-4.3.4.jar、httpclient-cache-4.3.4.jar、httpcore-4.3.2.jar、httpmime-4.3.4.jar、httpmime-4.3.4.jar;
大家可以到apache的官方網站:http://hc.apache.org/downloads.cgi 去下載相關的包;
import java.io.File; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class ClientMultipartFormPostTest { private static ExecutorService pool = Executors.newFixedThreadPool(300); public static void main(String[] args) throws Exception { final String path = args[0];//文件地址 final String url = args[1]; //調用的URL final int i_len = Integer.parseInt(args[2]);//線程總數 final int j_len = Integer.parseInt(args[3]);//每個線程的請求數(暫時沒用到) final AtomicInteger c = new AtomicInteger(0); final long s = System.currentTimeMillis(); for (int i = 0; i < i_len; i++) { new Thread(new Runnable() { @Override public void run() { while (true) { try { upLoadLogMultiThread(url,path); int cc = c.addAndGet(1); if (cc % 1000 == 0) { System.out.println(String.format("c: %d, t: %d", cc, (System.currentTimeMillis() - s))); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } } public static void upLoadLogMultiThread(String url,String path) throws IOException{ CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost(url); FileBody bin = new FileBody(new File(path)); StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN); HttpEntity reqEntity = MultipartEntityBuilder.create() .addPart("bin", bin) .addPart("comment", comment) .build(); httppost.setEntity(reqEntity); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity resEntity = response.getEntity(); EntityUtils.consume(resEntity); } finally { response.close(); } } finally { httpclient.close(); } } } |
測試結果,如圖所示:
我們程序的邏輯是每請求1000次,打印一次;
上面的結果翻譯的結果就是:
1----請求1000次,耗費時間為3727毫秒;
1----請求2000次,耗費時間為6253毫秒;
1----請求3000次,耗費時間為8713毫秒;
1----請求4000次,耗費時間為11028毫秒;
1----請求5000次,耗費時間為13340毫秒;
…
依據上面的結果,我們可以做個預估:每秒可以承受的4000次請求;也就是說我們可以大大預估一天有3千萬次請求數,這個程序都是可以應付對的;
但是上面的結論并沒說明文件,考慮到并發用戶的情況,好!那我們分1個并發,10個并發,100個并發,1000個并發,(我的并發是以線程來區分級別,估計大多數測試工具也是以這樣的一種方式去區分,備注:線程并非同一時刻,據本人了解,線程的區分度大概納秒級別的,還是在同一個進程里面去處理;而進程是可以利用上多核CPU的,舉例:4個核的CPU,開4個進程是可以時刻并行的運行,也就是說這4個進程是同一時刻在跑。)
10線程并發:
也就是說10個并非,每秒執行9千+;
100個線程并非:
也就是說100并非,每秒執行1.5萬次;
1000個并非:
已經掛掉了,也就是說這個小的后端程序能夠承受的并非級別是100~1000之間(一臺主機的情況,如果是集群的話,100萬臺服務器的話,相當于并發在1億~10億之間,如果按照業界傳聞facebook的幾十萬臺,Google級百萬臺,在還沒考慮主機CPU、內存的這個測試結果是非??捎^,目前主機是雙核2G內存的主機);
測試方法就是:java -jar errlogClient.jar path url n c
各個參數的標識:path = 目標文件路徑 ; url = 請求的地址 ; n = 線程總數 ; c = 每個線程調用請求的次數(備注目前上面的程序我是做循環跑的,所以暫時沒用上,大家覺得如果需要用上的話可以改改上面的程序)
這個工具如果大家覺得還湊合用的話就盡管拿去用吧~
posted on 2014-07-23 09:22 順其自然EVO 閱讀(330) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄