概述
編程的內核是數學,而測試的本質是計算,專業名詞叫容量預估,而測試的大體就是用程序模擬程序,檢測程序的正確性,有兩個點需要注意,QPS最佳值和系統接收最大值,根據測試數據的反饋,針對測試的現象和反映進行優化。
Jmeter 的基礎使用
在所有的開發準備就緒的時候,開始準備和上線有關的事情:測試和服務部署,測試要注意代碼的邏輯嚴謹、代碼運行的正確,服務穩定,所有的一切都需要用數據做指標,所有的計算機編程歸根結底都是數學。
step.01 Thread Group 線程組設置
jmeter自帶的thread group非常簡單。 一個thread 代表一個vuser,那么我們如果需要多少用戶并發,設置多少線程數即可。ramp-up period, 本人理解是多少時間從0個 vuser 上升到您指定的vusers數。從這些參數可以看,非常簡單。但不能設置測試的時間,這一點不是特別善解人意。不過還好我們有jmeter plugins, 帶的thread group 添加了這個功能。
(資料圖片)
Number of Threads(users) //并發線程(用戶)數Loop Count //重復執行次數
step.02 添加測試主體
右鍵單擊左側導航樹中的 Test Plan,選擇 Add > Threads(Users) > Thread Group ,右鍵單擊 Thread Group,選擇 Add > Sampler,可看到以下新增的采樣器選項,具體說明如下。
WebSocket Open Connection// 建立一個 WebSocket 連接WebSocket Ping/Pong // 控制幀,發送 ping 并接收 pongWebSocket request-response Sampler //發送和接收文本或二進制 WebSocket 幀WebSocket Single Write Sampler// 發送文本或二進制 WebSocket 幀WebSocket Single Read Sampler// 接收文本或二進制 WebSocket 幀WebSocket Close // 關閉 Websocket 連接
step.03 添加結果樹 選擇 Add > Listener ,結果樹都在這個下面。
添加聚合報告,執行測試,結果如下圖。
準備測試數據
實踐01 - 準備測試數據
1.隨機讀取用戶表里1000個用戶,進行壓力測試
select user_id from user where user_status = 1ORDER BY RAND() limit 1000;
2.構造測試需要的數據(10w條為例)
drop procedure idata;delimiter ;;create procedure idata()begin declare i int; set i=1; while(i<=100000 )do insert into t2 values(i, i, i); set i=i+1; end while;end;;delimiter ;call idata();
3.查詢最大鏈接數命令
show variables like "%max_connections%";
4.查詢鏈接線程的狀態命令
show processlist;
5.檢測服務器Mysql鏈接狀態的命令
netstat -ant|grep ESTABLISHED|grep 3306 | wc -l
實踐02 - 代碼部分
請求接口的Demo,主要的思考點在于用戶訪問具有隨機性,模擬數據時盡量做到接近真實場景,代碼如下:
$str = "62210,45783,36209,146502,24599,168338,166511,1917...";$uidTestArr = explode(",",$str);foreach ($uidTestArr as $uid){ if(isset($uid) && intval($uid) > 0){ $json = file_get_contents("http://open.stark.com/login/gettoken?uid=". $uid); $json = json_decode($json,true); $temp[] = [ "uid" => $uid , "token" => $json["token"] ]; }}$index = rand(0,count($temp) - 1);$randData = $temp[$index];//隨機執行結果/**Array( [uid] => 166511 [token] => f46540f11a40afeb9998cbe76661ec8234a87054)*/
Crontab的測試代碼Demo,先灌入測試數據,考慮的是Crontab的實際吞吐能力,優化計劃任務的執行間隔,使用Curl和shell_exec實現,執行結果,返回數據 {"code":200,"result":[],"msg":"OK"}
$str = "62210,45783,36209,146502,24599,168338,166511,1917,135799,8326...";//去掉可能存在的換行和空格$str = str_replace(array(PHP_EOL, " " ,"",$str));$testUsers = explode(",",$str);for ($i=0;$i<10000;$i++){ $index = rand(0,99); $uid = $testUsers[$index]; $msg = "{\"rid\":225,\"uid\":".$uid.",\"top_rid\":225,\"module\":\"novel_chapter\",\"module_name\":\"1022 last dance \u7b2c13\u7ae0\",\"module_id\":1019712,\"module_nid\":163961,\"comment_uid\":268,\"comment_nickname\":\"\u6d4b\u8bd5\u5c0f\u5b9d\u8d1d\",\"content\":\"\u4f60\u597d\u554a\",\"gift_id\":0,\"gift_name\":\"\",\"gift_number\":0}"; $url = "http://msgdev.stark.com/api/comment/message"; $json = shell_exec( "curl -d "uid={$uid}&msg={$msg}" {$url} " ); echo "i:".$i.",json:".$json.PHP_EOL;}
在臨時執行或停止計劃任務,在執行前加入時間毫秒的時間戳,可以打印代碼進行耗時計算,代碼如下:
//返回當前的毫秒時間戳function msectime() { $stamptime = microtime(); $arr = explode(" ",$stamptime ); $msectime = sprintf("%.0f", (floatval($arr[0]) + floatval($arr[1])) * 1000); return $msectime;}
總結:
并發鏈接和并發查詢:并發鏈接只是多消耗一點內存,并發查詢才是CPU的殺手。對系統的流量提前進行容量評估,歸根結底為計算問題,不管多大的流量最后的解決辦法都采用分而治之的策略。手動的效率太低,用程序測試程序。減少不必要的日志寫入,以減少磁盤I/O的傳輸。緩存和Mysql是一種平衡,需要去計算。第5點特殊說明有一點事特別需要強調的,不用被所謂的100w或者1000w流量的標題嚇倒,比如1000w/h的訪問量,Qps就變成了27777/s,每個用戶請求的熱門接口30個,這才是測試的真相,關鍵地方使用內存數據庫進行加速,障礙就迎刃而解了:
10000000 / 60 / 60 / 30 = 925/s
關鍵詞: