JAVA + LR實現(xiàn)apache流媒體的性能測試

點擊鏈接加入QQ群 522720170(免費公開課咪橙、視頻應(yīng)有盡有):https://jq.qq.com/?_wv=1027&k=5C08ATe

最近的一個項目野来,視頻點播系統(tǒng),使用apache實現(xiàn)的流媒體服務(wù)器。其實準(zhǔn)確的說叫做偽流(HTTP Pseudo-Streaming),基本原理和概念自行了解吧祟滴。

讓我簡單的描述就是仍然是HTTP下載,播放器播放本地緩存歌溉。只不過它也實現(xiàn)了一些和正規(guī)流媒體服務(wù)類似的功能垄懂。視頻點播類系統(tǒng)的性能測試,說簡單了主要就是模擬大量用戶去看視頻痛垛。服務(wù)端監(jiān)控整體性能草慧,客戶端關(guān)注各自表現(xiàn)。這里難點主要在于如何模擬大量用戶觀看視頻匙头?如何判斷各客戶端展現(xiàn)漫谷?

多客戶端的模擬無外乎3種方法:

1.全公司總動員,一起看乾胶。

2.一臺機器開多個播放頁面(或者是一個頁面上嵌入多個播放器)抖剿,調(diào)用多臺機器朽寞。

3.拋棄客戶端的解碼播放過程识窿,直接想法下載視頻文件。

第一種方法不用說脑融,雖然最真實喻频,但太原始沒有技術(shù)含量,如果是小公司人還不一定夠肘迎。

第二種方法在需要測試的用戶數(shù)不大時還可以甥温,否則會占用較多資源,而且技術(shù)含量也較低妓布。這種方式姻蚓,一臺機器上能模擬的用戶數(shù)很有限,因為CPU會很快成為瓶頸匣沼。

第三種方法最高效狰挡,在千兆網(wǎng)環(huán)境下,一臺機器可以模擬很多路用戶,此時網(wǎng)絡(luò)帶寬是瓶頸(如果帶寬更大加叁,估計硬盤IO就是瓶頸了)倦沧。但是沒有解碼和播放,如何判斷客戶端的效果呢它匕?兩種方式展融,一是對比下載速度和碼率,理論上只要下載速度足夠就可以了豫柬;二是測試過程中也可以打開幾個真實的播放窗口來驗證播放效果告希,因為壓力在服務(wù)端,可以認為每個客戶端都是等價的烧给。

本文要講的就是第三種測試方法暂雹。

以前還測過FMS的流媒體,網(wǎng)上可以找到現(xiàn)成的工具來實現(xiàn)本方法创夜,只要調(diào)用就可以了杭跪。但HTTP的這次也搜了兩天,好像還真沒有驰吓,只好自己動手了涧尿。看來最高效的方法檬贰,實現(xiàn)起來卻是最麻煩的姑廉。基本思路是JAVA實現(xiàn)下載功能翁涤,用LR的JAVA Vuser實現(xiàn)多用戶的控制桥言。動手前先給自己整理了一個需求

功能:

模擬下載√

播放列表√

下載速度記錄:總平均速度、每秒速度√

*偽裝成播放器進行連接

*客戶端限速

測試結(jié)果:

apache限速

下載速度

文件完整

功能擴展

jar包或者exe文件傳參(播放列表)

打?qū)︺^的是已經(jīng)實現(xiàn)了葵礼,帶星號的是未實現(xiàn)号阿、也不一定需要實現(xiàn)的高級功能。通過測試程序鸳粉,需要得到的結(jié)果是下載是否正確完成扔涧?下載速度是否足夠?apache的限速模塊是否起作用(如果開啟)届谈?這里可能會有個問題枯夜,如果下載程序突破了apache的限速,那有可能是測試程序的問題艰山,這就引出了上面的高級功能“偽裝成播放器”湖雹。

下面直接貼代碼,說明盡量放到注釋里曙搬。

下載類摔吏,提供靜態(tài)方法汤踏。

package com.test;

import java.io.*;

import java.net.*;

import java.util.*;

public class DownloadFile {

? ? /*

? ? *下載指定URL的文件

? ? *userid是用于保存本地文件的標(biāo)識

? ? **/

? ? public static int getHttpFileByUrl(String address, String userid) {

? ? ? ? int bufferSize = 1024;

? ? ? ? int size = 0;

? ? ? ? byte[] buf = new byte[bufferSize];


? ? ? ? /*

? ? ? ? *下載時間字符串

? ? ? ? *用于文件標(biāo)識

? ? ? ? *格式201210260130

? ? ? ? **/? ? ? ?

? ? ? ? Date date = new Date();

? ? ? ? SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMddHHmmss");

? ? ? ? String downloadTime = formatDate.format(date);


? ? ? ? /*

? ? ? ? ? *計算下載速度相關(guān)

? ? ? ? ? */

? ? ? ? int totalDownloadSize = 0;

? ? ? ? int lastDownloadSize = 0;

? ? ? ? long lastCheckTime = 0;

? ? ? ? long startDownloadTime = 0;

? ? ? ? int sec = 0;


? ? ? ? /*

? ? ? ? *下載和計算過程

? ? ? ? */

? ? ? ? try {

? ? ? ? ? ? URL url = new URL(address);

? ? ? ? ? ? URLConnection conn = url.openConnection();

? ? ? ? ? ? BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());

? ? ? ? ? ? FileOutputStream fos = new FileOutputStream("e:\test\testvideo" + "_" + downloadTime + "_" + userid);


? ? ? ? ? ? System.out.println("File Size:" + conn.getContentLength()/1024 + "KB");


? ? ? ? ? ? startDownloadTime = System.currentTimeMillis();

? ? ? ? ? ? lastCheckTime = startDownloadTime;


? ? ? ? ? ? while ((size = bis.read(buf)) != -1)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? fos.write(buf,0,size);

? ? ? ? ? ? ? ? totalDownloadSize += size;


? ? ? ? ? ? ? ? /*

? ? ? ? ? ? ? ? *計算每秒下載速度

? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? if (System.currentTimeMillis() - lastCheckTime > 1000) {

? ? ? ? ? ? ? ? ? ? System.out.println(sec + ": " + (totalDownloadSize - lastDownloadSize)/1024 + "KB");

? ? ? ? ? ? ? ? ? ? lastCheckTime = System.currentTimeMillis();

? ? ? ? ? ? ? ? ? ? lastDownloadSize = totalDownloadSize;

? ? ? ? ? ? ? ? ? ? sec++;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }


? ? ? ? ? ? System.out.println("Vuser " + userid + " Download Completed!");

? ? ? ? ? ? System.out.println("Average Download Speed: " + (totalDownloadSize/1024)/((System.currentTimeMillis() - startDownloadTime)/1000) + "KB/s");


? ? ? ? ? ? fos.close();

? ? ? ? ? ? bis.close();


? ? ? ? }catch (MalformedURLException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }


? ? ? ? return totalDownloadSize/1024;

? ? }? ?

}

測試驅(qū)動。

import com.test.*;

import java.util.*;

import java.io.*;

public class DownloadDrive {

? ? public static void main (String[] args) {


? ? ? ? //System.out.println("test");

? ? ? ? //DownloadFile.test();


? ? ? ? /*

? ? ? ? *調(diào)用者測量

? ? ? ? *自行實現(xiàn)

? ? ? ? */

? ? ? ? int DownLoadSize = 0;

? ? ? ? double DownLoadTime = 0;

? ? ? ? int Speed = 0;


? ? ? ? String url;

? ? ? ? ArrayList urlList = new ArrayList();

? ? ? ? /*

? ? ? ? *讀取待下載的URL地址

? ? ? ? *保存到list中

? ? ? ? */

? ? ? ? try{

? ? ? ? ? ? BufferedReader br = new BufferedReader(new FileReader("url.txt"));

? ? ? ? ? ? while((url = br.readLine()) != null){

? ? ? ? ? ? ? ? urlList.add(url);

? ? ? ? ? ? }? ?

? ? ? ? }catch(IOException ie){

? ? ? ? ? ? ie.printStackTrace();

? ? ? ? }


? ? ? ? System.out.println("Total URLs: " + urlList.size());


? ? ? ? /*

? ? ? ? *依次下載list中的文件

? ? ? ? */

? ? ? ? for(int i = 0; i < urlList.size(); i++){

? ? ? ? ? ? url = (String)urlList.get(i);

? ? ? ? ? ? System.out.println(url);? ? ? ? ? ?

? ? ? ? ? ? //傳入url和每個調(diào)用者的標(biāo)識

? ? ? ? ? ? DownloadFile.getHttpFileByUrl(url, "1");

? ? ? ? }

? ? }? ?


}

將待下載的URL保存到url.txt中舔腾,每行一個地址溪胶。文件放到DownloadDrive.class同目錄中。

到這稳诚,主要代碼已經(jīng)實現(xiàn)了哗脖。下一步需要做的是和LR整合,用LR的Java Vuser對下載功能進行控制扳还,模擬多用戶才避。其實也就是重寫一個測試驅(qū)動,只不過這個驅(qū)動是需要LR內(nèi)部方法了氨距,應(yīng)該沒有什么技術(shù)上的難點了桑逝。


接下來,通過LoadRunner來實現(xiàn)多線程的模擬和控制俏让。

新建LR的JAVA Vuser腳本楞遏,這里可以直接進行JAVA編碼,又可以調(diào)用LR的內(nèi)部方法首昔,如事務(wù)寡喝、思考時間、集合點等等勒奇。到了這步已經(jīng)沒有任何難點了预鬓,開發(fā)人員只要花1個小時了解下LR的基本使用和常用方法即可,測試人員如果不會JAVA……那還是算了吧赊颠。

Action.java內(nèi)容如下:

import lrapi.lr;

import com.test.*;

import java.util.*;

import java.io.*;

public class Actions

{

? ? public int init() throws Throwable {

? ? ? ? return 0;

? ? }//end of init

? ? public int action() throws Throwable {


? ? ? ? /*

? ? ? ? 調(diào)用者測量

? ? ? ? */

? ? ? ? int downloadSize = 0;

? ? ? ? int downloadTime = 0;

? ? ? ? long startTime = 0;

? ? ? ? long endTime = 0;

? ? ? ? int speed = 0;

? ? ? ? int vid;

? ? ? ? vid = lr.get_vuser_id();

? ? ? ? /*

? ? ? ? 從url文件生成arraylist

? ? ? ? ? ? */

? ? ? ? String url;

? ? ? ? ArrayList urlList = new ArrayList();

? ? ? ? try{? ? ? ?

? ? ? ? ? ? ? ? BufferedReader br = new BufferedReader(new FileReader("url.txt"));

? ? ? ?      while((url = br.readLine()) != null){

? ? ? ? ? ?    urlList.add(url);

? ? ? ? }

? ? ? ? }catch(IOException ie){

? ? ? ?   ie.printStackTrace();

? ? ? ? }

? ? ? ? lr.enable_redirection(true);

? ? ? ? lr.set_debug_message(lr.MSG_CLASS_JIT_LOG_ON_ERROR, lr.SWITCH_OFF);

? ? ? ? System.out.println("Total URLs: " + urlList.size());

? ? ? ? for(int i = 0; i < urlList.size(); i++){

? ? ? ?   url = (String)urlList.get(i);

? ? ? ?   System.out.println(url);

? ? ? ?   //事務(wù)名稱

? ? ? ?   String trxName = "URL" + (i+1);

? ? ? ?   startTime = System.currentTimeMillis();

? ? ? ?   lr.start_transaction(trxName);

? ? ? ?   //傳入url和每個調(diào)用者的標(biāo)識

? ? ? ?   downloadSize = DownloadFile.getHttpFileByUrl(url, Integer.toString(vid));

? ? ? ?   lr.end_transaction(trxName, lr.AUTO);

? ? ? ?   endTime = System.currentTimeMillis();

? ? ? ?   downloadTime = (int)(endTime - startTime)/1000;

? ? ? ?   speed = downloadSize / downloadTime;

? ? ? ?   lr.output_message(trxName + ": completed");

? ? ? ?   lr.output_message("time cost: " + downloadTime + "s");

? ? ? ?   lr.output_message("average speed: " + speed + "KB/s");

? ? ? ?   lr.output_message("");

? ? ? ? }

? ? ? ? lr.set_debug_message(lr.MSG_CLASS_JIT_LOG_ON_ERROR, lr.SWITCH_ON);

? ? ? ? return 0;

? ? }//end of action

? ? public int end() throws Throwable {

? ? ? ? return 0;

? ? }//end of end

}

所有以lr開頭的方法都是LR內(nèi)部方法格二,這里只用到了事務(wù)、日志等幾個竣蹦。

編譯之前我們的JAVA下載代碼顶猜,將包(com.test)放入LR腳本的目錄中,如圖:

打開LR腳本草添,運行試一下驶兜。

可以看到正常輸出了日志扼仲,再驗證一下下載到的文件是否完整远寸,找到輸出路徑,如“h:testtestvideo_20121106194419_-1”屠凶,用播放器打開這個文件驰后,正常播放。說明我們的腳本已經(jīng)OK了矗愧,下面就要做多用戶的測試了灶芝。

打開controller郑原,設(shè)置同時運行2個VUSER(為了保證負載機的網(wǎng)絡(luò)不成為瓶頸),運行場景夜涕。

可以看到犯犁,2個VUSER都按預(yù)期正常完成了。

從幾個方面驗證測試的有效性:

1是負載機的網(wǎng)絡(luò)利用女器,上面單用戶執(zhí)行腳本時下載速度是5M/s(apache服務(wù)器做了限速)酸役,這次兩個用戶同時下載達到了10M。

2是每個VUSER的輸出日志驾胆。

3是下載文件的完整性涣澡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丧诺,隨后出現(xiàn)的幾起案子入桂,更是在濱河造成了極大的恐慌,老刑警劉巖驳阎,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抗愁,死亡現(xiàn)場離奇詭異,居然都是意外死亡呵晚,警方通過查閱死者的電腦和手機驹愚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劣纲,“玉大人逢捺,你說我怎么就攤上這事●荆” “怎么了劫瞳?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绷柒。 經(jīng)常有香客問我志于,道長,這世上最難降的妖魔是什么废睦? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任伺绽,我火速辦了婚禮,結(jié)果婚禮上嗜湃,老公的妹妹穿的比我還像新娘奈应。我一直安慰自己,他們只是感情好购披,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布杖挣。 她就那樣靜靜地躺著,像睡著了一般刚陡。 火紅的嫁衣襯著肌膚如雪惩妇。 梳的紋絲不亂的頭發(fā)上株汉,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音歌殃,去河邊找鬼乔妈。 笑死,一個胖子當(dāng)著我的面吹牛氓皱,可吹牛的內(nèi)容都是我干的褒翰。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼匀泊,長吁一口氣:“原來是場噩夢啊……” “哼优训!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起各聘,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤揣非,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后躲因,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體早敬,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年大脉,在試婚紗的時候發(fā)現(xiàn)自己被綠了搞监。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡镰矿,死狀恐怖琐驴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秤标,我是刑警寧澤绝淡,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站苍姜,受9級特大地震影響牢酵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衙猪,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一馍乙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垫释,春花似錦丝格、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茫船,卻和暖如春琅束,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背算谈。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工涩禀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人然眼。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓艾船,卻偏偏與公主長得像,于是被迫代替她去往敵國和親高每。 傳聞我的和親對象是個殘疾皇子屿岂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 第一章 初識javaJAVA 第一講:什么是程序?:為了讓計算機執(zhí)行某些操作或解決某個問題而編寫的一系列有序指令的...
    人子日月幾點閱讀 509評論 0 1
  • 一:LoadRunner常見問題整理1.LR 腳本為空的解決方法:1.去掉ie設(shè)置中的第三方支持取消掉2.在系統(tǒng)屬...
    0100閱讀 4,081評論 0 11
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,795評論 0 11
  • 貪心算法 貪心算法總是作出在當(dāng)前看來最好的選擇。也就是說貪心算法并不從整體最優(yōu)考慮鲸匿,它所作出的選擇只是在某種意義上...
    fredal閱讀 9,207評論 3 52
  • /*【程序21】 * 作者 南楓題目:求1+2!+3!+...+20!的和 1. 程序分析:此程序只是把累加變成了...
    HUC南楓閱讀 430評論 0 0