實驗要求: javascript
1、總體目標php
安裝虛擬機,並安裝一套LAMP(Linux+Apache+Mysql+PHP)待測系統,推薦ECShop(http://www.ecshop.com),基於此進行Jmeter壓力測試,並在測試後得出Jmeter測試報告,並根據sysstat得出Linux服務器的CIMN(CPU、IO、Memory以及Network)的性能。html
2、隊員分工html5
3、實驗要求java
i. 報告封皮node
1) 實驗名稱、團隊名稱、隊長、成員以及每一個人完成任務的信息mysql
ii. 實驗相關內容:git
1) Linux下top命令結果截圖github
2) 訪問的B/S系統截圖sql
3) Jmeter的Testplan展開截圖
4) Beanshell代碼
5) 運行Jmeter測試以後的Aggregate Report Result
6) 運行Jmeter測試以後的服務器性能
4、 參考
實驗步驟:
1、安裝LAMP
安裝apache2
sudo apt-get update sudo apt-get install apache2
安裝MySQL
sudo apt-get install mysql-server mysql-client
安裝PHP5.6
sudo add-apt-repository ppa:ondrej/php //換源 sudo apt-get update sudo apt-get install php5.6 sudo apt-get install libapache2-mod-php5.6 sudo apt-get install php5.6-mysql php5.6-gd
提示:由於Ubuntu16.04默認下載的php版本是7.0,而 ecshop比較老,存在兼容性問題,因此卸載了php7.0再下載php5.6,卸載php:
sudo aptitude purge `dpkg -l | grep php| awk '{print $2}' |tr "\n" " "`
2、安裝ECShop
一、下載ECShop,解壓縮後將upload文件夾放在/var/www/html目錄下,命名爲ecshop,在瀏覽器中打開localhost/ecshop
檢測環境的時候提示:是否支持 JPEG是不支持的。 解決:查看發現有libjpeg.lib庫,GD2庫也有,都加載了,也都正常。查看ecshop源代碼發現var/www/html/ecshop/install/includes/lib_installer.php中第98行,JPEG寫成了JPG,正確的應該是: $jpeg_enabled = ($gd_info['JPEG Support'] === true) ? $_LANG['support'] : $_LANG['not_support'];
二、安裝ecshop遇到的問題
(1)Deprecated: preg_replace() 報錯,錯誤緣由:preg_replace() 函數中用到的修飾符 /e 在 PHP5.5.x 中已經被棄用了。
好比:Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in \includes\cls_template.php on line 300
原有內容:
return preg_replace("/{([^\}\{]*)}/e", "\$this->select('\\1');", $source);
修改後內容:
return preg_replace_callback("/{([^\}\{]*)}/", function($r) { return $this->select($r[1]); }, $source);
(2)Parse error: syntax error, unexpected 'endforeach' (T_ENDFOREACH) in /var/www/html/ecshop/temp/compiled/vote.lbi.php on line 13
修改後的vote.lbi.php爲:
<?php if ($this->_var['vote']): ?><?php echo $this->smarty_insert_scripts(array('files'=>'transport.js')); ?>
<html>
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<title></title>
</head>
<body>
<div id="ECS_VOTE">
<div class="box">
<div class="box_1">
<h3>
<span>
<?php echo $this->_var['lang']['online_vote']; ?>
</span>
</h3>
<div class="boxCenterList">
<form id="formvote" name="ECS_VOTEFORM" method="post" action="javascript:submit_vote()">
<?php $_from = $this->_var['vote']; if (!is_array($_from) && !is_object($_from)) {
settype($_from, 'array');
}; $this->push_vars('', 'title');if (count($_from)):
foreach ($_from AS $this->_var['title']):
?><?php echo $this->_var['title']['vote_name']; ?>
<br />(<?php echo $this->_var['lang']['vote_times']; ?>:<?php echo $this->_var['title']['vote_count']; ?>)
<br /><?php endforeach; endif; unset($_from); ?><?php $this->pop_vars();; ?>
<?php $_from = $this->_var['vote']; if (!is_array($_from) && !is_object($_from)) {
settype($_from, 'array');
}; $this->push_vars('', 'title');if (count($_from)):
foreach ($_from AS $this->_var['title']):
?> <?php $_from = $this->_var['title']['options']; if (!is_array($_from) && !is_object($_from)) {
settype($_from, 'array');
}; $this->push_vars('', 'item_0_30844800_1297167693');if (count($_from)):
foreach ($_from AS $this->_var['item_0_30844800_1297167693']):
?> <?php if ($this->_var['title']['can_multi'] == 0): ?>
<input type="checkbox" name="option_id"
value="<?php echo $this->_var['item_0_30844800_1297167693']['option_id']; ?>" />
<?php echo $this->_var['item_0_30844800_1297167693']['option_name']; ?>
(<?php echo $this->_var['item_0_30844800_1297167693']['percent']; ?>%)
<br /><?php else: ?>
<input type="radio" name="option_id"
value="<?php echo $this->_var['item_0_30844800_1297167693']['option_id']; ?>" />
<?php echo $this->_var['item_0_30844800_1297167693']['option_name']; ?>
(<?php echo $this->_var['item_0_30844800_1297167693']['percent']; ?>%)
<br /><?php endif; ?> <?php endforeach; endif; unset($_from); ?><?php $this->pop_vars();; ?>
<input type="hidden" name="type" value="<?php echo $this->_var['title']['can_multi']; ?>" />
<?php endforeach; endif; unset($_from); ?><?php $this->pop_vars();; ?>
<input type="hidden" name="id" value="<?php echo $this->_var['vote_id']; ?>" />
<input type="submit" name="submit" style="border:none;"
value="<?php echo $this->_var['lang']['submit']; ?>" class="bnt_bonus" />
<input type="reset" style="border:none;" value="<?php echo $this->_var['lang']['reset']; ?>"
class="bnt_blue" /></form>
</div>
</div>
</div>
</div>
<div class="blank5"></div>
<script type="text/javascript">
/**
* 處理用戶的投票
*/
function submit_vote()
{
var frm = document.forms[&amp;#39;ECS_VOTEFORM&amp;#39;];
var type = frm.elements[&amp;#39;type&amp;#39;].value;
var vote_id = frm.elements[&amp;#39;id&amp;#39;].value;
var option_id = 0;
if (frm.elements[&amp;#39;option_id&amp;#39;].checked)
{
option_id = frm.elements[&amp;#39;option_id&amp;#39;].value;
}
else
{
for (i=0; i&amp;lt;frm.elements[&amp;#39;option_id&amp;#39;].length; i++ )
{
if (frm.elements[&amp;#39;option_id&amp;#39;][i].checked){
option_id = (type == 0) ? option_id + &amp;quot;,&amp;quot; +
frm.elements[&amp;#39;option_id&amp;#39;][i].value :
frm.elements[&amp;#39;option_id&amp;#39;][i].value;
}
}
}
if (option_id == 0)
{
return;
}
else
{
Ajax.call(&amp;#39;vote.php&amp;#39;, &amp;#39;vote=&amp;#39; + vote_id +
&amp;#39;&amp;amp;options=&amp;#39; + option_id +
&amp;quot;&amp;amp;type=&amp;quot; + type,
voteResponse, &amp;#39;POST&amp;#39;, &amp;#39;JSON&amp;#39;);
}
}
/**
* 處理投票的反饋信息
*/
function voteResponse(result)
{
if (result.message.length &amp;gt; 0)
{
alert(result.message);
}
if (result.error == 0)
{
var layer = document.getElementById(&amp;#39;ECS_VOTE&amp;#39;);
if (layer)
{
layer.innerHTML = result.content;
}
}
}
</script> <?php endif; ?></body>
</html>
(3)Warning: file_put_contents(/var/www/html/ecshop/temp/compiled/vote.lbi.php): failed to open stream: Permission denied in /var/www/html/ecshop/includes/cls_template.php on line 262
Notice: can't write:/home/username/public_html/temp/compiled/page_header.lbi.php in /home/username/public_html/includes/cls_template.php on line 264
解決方法:修改tmep的權限sudo chmod 777 temp
(4)Strict Standards: Non-static method cls_image::gd_version() should not be called statically in ...install\includes\lib_installer.php on line 31
解決方法:將cls_image.php文件的gd_version方法改爲靜態方法,即static function。
3、安裝Jmeter
一、下載安裝 apache-jmeter-3.0
https://archive.apache.org/dist/jmeter/binaries/ 下載apache-jmeter-3.0.zip,解壓到 D:\document\apache-jmeter-3.0,添加系統變量JMETER_HOME,設置值爲 D:\document\apache-jmeter-3.0,打開 D:\document\apache-jmeter-3.0\bin 下的jmeter.bat,出現下面兩個窗口:
二、使用Jmeter對性能測試腳本進行錄製和回放
錄製:添加線程組
回放:右鍵線程組 添加監聽器aggregate report 和 view result tree,點擊運行(綠色三角形)按鈕:
Aggregate Report 10個字段,含義分別以下:
Label:每一個 JMeter 的 element(例如 HTTP Request)都有一個 Name 屬性,這裏顯示的就是 Name 屬性的值
#Samples:表示你此次測試中一共發出了多少個請求,若是模擬10個用戶,每一個用戶迭代10次,那麼這裏顯示100
Average:平均響應時間——默認狀況下是單個 Request 的平均響應時間,當使用了 Transaction Controller 時,也能夠以Transaction 爲單位顯示平均響應時間
Median:中位數,也就是 50% 用戶的響應時間
90% Line:90% 用戶的響應時間
Note:關於 50% 和 90% 併發用戶數的含義,請參考下文:http://www.cnblogs.com/jackei/archive/2006/11/11/557972.html
Min:最小響應時間
Max:最大響應時間
Error%:本次測試中出現錯誤的請求的數量/請求的總數
Throughput:吞吐量——默認狀況下表示每秒完成的請求數(Request per Second),當使用了 Transaction Controller 時,也能夠表示相似 LoadRunner 的 Transaction per Second 數
KB/Sec:每秒從服務器端接收到的數據量,至關於LoadRunner中的Throughput/Sec
PS1:在代理服務器啓動後,要打開瀏覽器的代理設置
PS2:打開代理後好比訪問百度首頁,會顯示 您的鏈接不安全,說明JMeter數字證書是不被信任的,接下來咱們就須要將該證書導入到瀏覽器的根證書列表中以達到人工配置信任的目的。瀏覽器設置裏 管理證書:
三、被測腳本參數化
四、用PostProcesser獲取響應中的關鍵數據
使用CSS/JQuery Extractor獲取響應數據
五、用BeanShellAssersion判斷響應是否正確
4、Top命令
top命令 參考http://www.javashuo.com/article/p-fqgnidpj-bu.html
其中,
PID:進程ID,進程的惟一標識符
USER:進程全部者的實際用戶名。
PR:進程的調度優先級。這個字段的一些值是'rt'。這意味這這些進程運行在實時態。
NI:進程的nice值(優先級)。越小的值意味着越高的優先級。負值表示高優先級,正值表示低優先級
VIRT:進程使用的虛擬內存。進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES
RES:駐留內存大小。駐留內存是任務使用的非交換物理內存大小。進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA
SHR:SHR是進程使用的共享內存。共享內存大小,單位kb
S:這個是進程的狀態。它有如下不一樣的值:
%CPU:自從上一次更新時到如今任務所使用的CPU時間百分比。
%MEM:進程使用的可用物理內存百分比。
TIME+:任務啓動後到如今所使用的所有CPU時間,精確到百分之一秒。
COMMAND:運行進程所使用的命令。進程名稱(命令名/命令行)
5、安裝sysstat並使用sysstat查看Linux服務器的CIMN的性能
$sudo apt-get install sysstat
sar命令介紹:摘自 https://blog.csdn.net/hguisu/article/details/7493661
sar命令能夠從文件的讀寫狀況、系統調用的使用狀況、磁盤I/O、CPU效率、內存使用情況、進程活動及IPC有關的活動等方面進行報告。
命令格式:sar [options] [-A] [-o file] t [n]
t爲採樣間隔,n爲採樣次數,默認值是1
-o file表示將命令結果以二進制格式存放在文件中,file 是文件名。
options 爲命令行選項
-A:全部報告的總和
-u:輸出總體CPU使用狀況的統計信息
-v:輸出inode、文件和其餘內核表的統計信息
-d:輸出每個塊設備的活動信息
-r:輸出內存和交換空間的統計信息
-b:顯示I/O和傳送速率的統計信息
-a:文件讀寫狀況
-c:輸出進程統計信息,每秒建立的進程數
-R:輸出內存頁面的統計信息
-y:終端設備活動狀況
-w:輸出系統交換活動信息
一、CPU監控
總體CPU使用統計:sar -u -o test_sar 1 1
輸出項說明:
CPU:all表示統計信息爲全部 CPU的平均值。
%user:顯示在用戶級別(application)運行使用 CPU 總時間的百分比。
%nice:顯示在用戶級別,用於nice操做,所佔用 CPU總時間的百分比。
%system:在覈心級別(kernel)運行所使用 CPU總時間的百分比。
%iowait:顯示用於等待I/O操做佔用 CPU總時間的百分比。
%steal:管理程序(hypervisor)爲另外一個虛擬進程提供服務而等待虛擬 CPU 的百分比。
%idle:顯示 CPU空閒時間佔用 CPU總時間的百分比。
PS:
1.若 %iowait的值太高,表示硬盤存在I/O瓶頸
2.若 %idle的值高但系統響應慢時,有多是 CPU等待分配內存,此時應加大內存容量
3.若 %idle的值持續低於1,則系統的 CPU處理能力相對較低,代表系統中最須要解決的資源是 CPU
因爲test_sar是二進制文件中的內容, 當你用cat看test_sar時發現全都是亂碼,彆着急,sar爲你準備了-f filename選項,你只要用 -f 設定要讀取的信息存儲文件,就能夠清晰地讀出信息了。
好比sar -f test_sar。
若是個人CPU是多核處理器,那麼sar能知道某一個核的運行信息麼?
徹底沒問題的。有一個選項-P,就是用來爲多核處理器而設計的。
當在使用sar命令而沒有設定-P選項時,sar會根據全部核給出一個宏觀彙報,也就是平均的值。
若是使用了-P選項來指定某一個核,那麼就會針對這個單獨的核給出具體性能信息。
當使用-P ALL時,sar就會根據每個核都給出其具體性能信息,而後再給出一個總的性能信息。
監控進程隊列長度和平均負載狀態:sar -q 1 1
輸出項說明:
runq-sz:運行隊列的長度(等待運行的進程數)
plist-sz:進程列表中進程(processes)和線程(threads)的數量
ldavg-1:最後1分鐘的系統平均負載(System load average)
ldavg-5:過去5分鐘的系統平均負載
ldavg-15:過去15分鐘的系統平均負載
二、內存和交換空間監控
sar -r 1 2
輸出項說明:
kbmemfree:這個值和free命令中的free值基本一致,因此它不包括buffer和cache的空間.
kbmemused:這個值和free命令中的used值基本一致,因此它包括buffer和cache的空間.
%memused:這個值是kbmemused和內存總量(不包括swap)的一個百分比.
kbbuffers和kbcached:這兩個值就是free命令中的buffer和cache.
kbcommit:保證當前系統所須要的內存,即爲了確保不溢出而須要的內存(RAM+swap).
%commit:這個值是kbcommit與內存總量(包括swap)的一個百分比.
監控內存分頁:sar -B 1 2
輸出項說明:
pgpgin/s:表示每秒從磁盤或SWAP置換到內存的字節數(KB)
pgpgout/s:表示每秒從內存置換到磁盤或SWAP的字節數(KB)
fault/s:每秒鐘系統產生的缺頁數,即主缺頁與次缺頁之和(major + minor)
majflt/s:每秒鐘產生的主缺頁數.
pgfree/s:每秒被放入空閒隊列中的頁個數
pgscank/s:每秒被kswapd掃描的頁個數
pgscand/s:每秒直接被掃描的頁個數
pgsteal/s:每秒鐘從cache中被清除來知足內存須要的頁個數
%vmeff:每秒清除的頁(pgsteal)佔總掃描頁(pgscank+pgscand)的百分比
監控系統交換活動信息:sar -W 1 2
輸出項說明:
pswpin/s:每秒系統換入的交換頁面(swap page)數量
pswpout/s:每秒系統換出的交換頁面(swap page)數量
三、I/O和傳送速率監控
緩衝區的使用狀況:sar -b 1 2
輸出項說明:
tps:每秒鐘物理設備的 I/O 傳輸總量
rtps:每秒鐘從物理設備讀入的數據總量
wtps:每秒鐘向物理設備寫入的數據總量
bread/s:每秒鐘從物理設備讀入的數據量,單位爲 塊/s
bwrtn/s:每秒鐘向物理設備寫入的數據量,單位爲 塊/s
設備使用狀況:sar -d 1 2
其中:
參數-p能夠打印出sda,hdc等磁盤設備名稱,若是不用參數-p,設備節點則有多是dev8-0,dev22-0
tps:每秒從物理磁盤I/O的次數.多個邏輯請求會被合併爲一個I/O磁盤請求,一次傳輸的大小是不肯定的.
rd_sec/s:每秒讀扇區的次數.
wr_sec/s:每秒寫扇區的次數.
avgrq-sz:平均每次設備I/O操做的數據大小(扇區).
avgqu-sz:磁盤請求隊列的平均長度.
await:從請求磁盤操做到系統完成處理,每次請求的平均消耗時間,包括請求隊列等待時間,單位是毫秒
svctm:系統處理每次請求的平均時間,不包括在請求隊列中消耗的時間.
%util:I/O請求佔CPU的百分比,比率越大,說明越飽和.
PS:
1. avgqu-sz 的值較低時,設備的利用率較高。
2. 當%util的值接近 100% 時,表示設備帶寬已經佔滿。
四、Network監控
sar -n DEV 1 2
運行Jmeter測試以後的Aggregate Report 截圖:
sudo gedit /etc/default/sysstat, 將 ENABLED=「false「 改成ENABLED=「true「
sudo /etc/init.d/sysstat restart
sysstat 監控服務器性能截圖:
5*10:由上至下分別爲:cpu,memory,IO,網絡,內存分頁監控,設備使用狀況。 命令爲 sar -u ,sar -q;sar -r;sar -b;sar -n DEV;sar -B;sar-d。.
內存分頁監控