公司最近要使用CDN,为了能测试下在加入CDN后的效果,需要对网站做一个基准测试。以下是实现方式。
以下是对网站数据的采集,使用screen运行php index.php
index.php
<?php include(__DIR__.'/mysql.php'); include(__DIR__.'/config.php'); include(__DIR__.'/helper.php'); while(1) { $db = new Mysql(); $db->connect($config['db']); $create_time = strtotime(date('Y-m-d H:i',time())); //######################2M图片############################# //无CDN $start = get_microtime(); $status = curl('http://27.54.226.101:99/scenicInt/0/6/2/101062/101062.jpg'); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,1,2,$create_time)"); //使用CDN $start = get_microtime(); $status = curl('http://image.yhiker.com/scenicInt/0/6/2/101062/101062.jpg'); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,1,1,$create_time)"); //######################12M离线包############################# //无CDN $start = get_microtime(); $status = curl("http://27.54.226.101:99/0086/itinerary/01000000379-0.zip"); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,2,2,$create_time)"); //使用CDN $start = get_microtime(); $status = curl("http://image.yhiker.com/0086/itinerary/01000000379-0.zip"); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,2,1,$create_time)"); //######################API接口数据############################# //无CDN $start = get_microtime(); $status = curl('http://27.54.226.101:98/haiyouapi/services',array('command'=>8101,'platformType'=>'web','param'=>array('itineraryId'=>'01000000599'))); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,3,2,$create_time)"); //使用CDN $start = get_microtime(); $status = curl('http://api.yhiker.com/haiyouapi/services',array('command'=>8101,'platformType'=>'web','param'=>array('itineraryId'=>'01000000599'))); $end = get_microtime(); $time = sprintf("%s",($end - $start)); if( !$status ) { $time = -1; } $db->ping($config['db']); $db->query("insert into benchmark(time,type,category,create_time) value($time,3,1,$create_time)"); unset($start); unset($status); unset($end); unset($time); unset($db); sleep(120); } ?>
config.php
<?php header('Content-type:text/html;charset=utf-8'); ini_set('date.timezone','Asia/Shanghai'); set_time_limit(0); error_reporting(E_ERROR); ini_set('memory_limit', '1024M'); $config['db'] = array ( 'host' => '192.168.1.188:3000', 'user' => 'xupeng', 'pass' => 'xupeng', 'db' => 'test', 'pconnect' => false, 'dbcharset' => 'utf8', );helper.php
<?php function get_microtime() { list($usec, $sec) = explode(' ', microtime()); return ((float)$usec + (float)$sec); } function curl($url, $data = array(), $timeout = 20) { $ch = curl_init(); if (is_array($data) && $data) { $formdata = json_encode($data); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_POSTFIELDS, $formdata); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $result = curl_exec($ch); $response = curl_getinfo( $ch ); curl_close($ch); if( $response['http_code'] == 200 ) { return true; } else { return false; } }mysql.php
<?php class mysql { var $dbhost; //数据库地址 var $dbuser; //数据库用户名 var $dbpasswd; //数据库密码 var $dbpconnect=0; //数据库长连接 var $dbname; //数据库名称 var $dbchart; //数据库链接编码 var $dblink; //数据库连接对象 var $sql; //sql语句 var $res; //sql语句执行结果 var $errno; //错误信息 function connect($dbConfig) { $this->dbhost = $dbConfig['host']; $this->dbuser = $dbConfig['user']; $this->dbpasswd = $dbConfig['pass']; $this->dbpconnect = $dbConfig['pconnect']; $this->dbname = $dbConfig['db']; $this->dbchart = $dbConfig['dbcharset']; if($this->dbpconnect) { $this->dblink = mysql_pconnect($this->dbhost,$this->dbuser,$this->dbpasswd,1) or die('can not connect to mysql database!'); } else { $this->dblink = mysql_connect($this->dbhost,$this->dbuser,$this->dbpasswd,1) or die('can not connect to mysql database!'); } mysql_query('set names '.$this->dbchart, $this->dblink); mysql_select_db($this->dbname, $this->dblink); unset($dbConfig); } /** * 数据库执行语句 * * @return blooean * */ function query($sql, $die_msg = 1) { $this->sql = $sql; $result = @mysql_query($sql, $this->dblink); //可以用自定义错误信息的方法,就要压制本身的错误信息 if($result == true) { return $result; } else { //有错误发生 $this->errno = mysql_errno($this->dblink); if($this->errno >0) { if($die_msg == 1) { //强制报错并且die $this->msg($sql); } else { return $this->errno;//无强制报错,则返回错误代码 } } } } /** * 获得查询语句单条结果 * * @return array * */ function get_one($sql) { $this->sql = $sql; $this->res = $this->query($sql); return mysql_fetch_assoc($this->res); } /** * 获得查询语句多条结果 * * @return array * */ function get_all($sql,$filed=null) { $this->sql = $sql; $this->res = $this->query($sql); $arr = array(); while($row = mysql_fetch_assoc($this->res)) { if( $filed ) { $arr[] = $row[$filed]; } else { $arr[] = $row; } } return $arr; } /** * 取得结果数据 * * @param resource $query * * @return string * */ function result($query, $row) { $query = @mysql_result($query, $row); return $query; } function affected_rows() { return mysql_affected_rows($this->dblink); } /** * 获得刚插入数据的id * * @return int id * */ function insert_id() { return ($id = mysql_insert_id($this->dblink)) >= 0 ? $id : $this->result($this->query('SELECT last_insert_id()'), 0); } /** * 关闭数据库连接,当您使用持续连接时该功能失效 * * @return blooean * */ function close() { return mysql_close($this->dblink); } function ping($dbconfig) { if(!mysql_ping($this->dblink)) { $this->close(); $this->connect($dbconfig); } } /** * 显示自定义错误 * */ function msg($sql) { if($this->errno) { //可以根据错误ID,配置好一些友好的错误信息提示语句 $msgArr = array(); $msgArr['1062'] = "唯一性索引有重复值插入"; /*...更多错误代码根据实际业务再添加...*/ if($msgArr[$this->errno]) { $errMsg = $msgArr[$this->errno];//已定义的错误 }else{ $errMsg = mysql_error();//未定义的错误,由默认的错误信息决定 } echo "数据库操作错误\n"; echo "错误代码:".$this->errno."\n"; echo "SQL语句:".$sql."\n"; echo "错误信息:".$errMsg."\n"; echo date('Y-m-d H:i:s',time())."\n"; unset($msgArr); die; } } function __destruct() { $this->dbhost; $this->dbuser; $this->dbpasswd; $this->dbpconnect; $this->dbname; $this->dbchart; $this->dblink; $this->sql; $this->res; $this->errno; } }
以下是数据报表的展示:
<?php include(__DIR__.'/config.php'); include(__DIR__.'/mysql.php'); $db = new mysql(); $db->connect($config['db']); $result = $db->get_all("select * from benchmark where category = 2 order by create_time desc limit 90"); //echo count($result);exit; $ret = array(); $total = array(); foreach( array_reverse($result) as $v) { $time_db = strtotime(date('Y-m-d H:i',$v['create_time'])); $time = intval(($time_db+28800).'000'); $ret[$v['type']] .= '['.$time.','.$v['time'].'],'; $total[$v['type']][] = ( $v['time'] > 0 ) ? $v['time'] : 0; } $pic = '['.chop($ret[1],',').']'; $zip = '['.chop($ret[2],',').']'; $api = '['.chop($ret[3],',').']'; $pic_average = array_sum($total[1]) / count($total[1]); $zip_average = array_sum($total[2]) / count($total[2]); $api_average = array_sum($total[3]) / count($total[3]); //CDN $result_cdn = $db->get_all("select * from benchmark where category = 1 order by create_time desc limit 90"); $ret_cdn = array(); $total_cdn = array(); foreach( array_reverse($result_cdn) as $v) { $time_db = strtotime(date('Y-m-d H:i',$v['create_time'])); $time = intval(($time_db+28800).'000'); $ret_cdn[$v['type']] .= '['.$time.','.$v['time'].'],'; $total_cdn[$v['type']][] = ( $v['time'] > 0 ) ? $v['time'] : 0; } $pic_cdn = '['.chop($ret_cdn[1],',').']'; $zip_cdn = '['.chop($ret_cdn[2],',').']'; $api_cdn = '['.chop($ret_cdn[3],',').']'; $pic_average_cdn = array_sum($total_cdn[1]) / count($total_cdn[1]); $zip_average_cdn = array_sum($total_cdn[2]) / count($total_cdn[2]); $api_average_cdn = array_sum($total_cdn[3]) / count($total_cdn[3]); $all = $db->get_all("select sum(time) as sum,sum(item) as id from benchmark where time != -1 and category = 2 GROUP BY type"); $pic_all_average = $all[0]['sum'] / $all[0]['id']; $zip_all_average = $all[1]['sum'] / $all[1]['id']; $api_all_average = $all[2]['sum'] / $all[2]['id']; $all_cdn = $db->get_all("select sum(time) as sum,sum(item) as id from benchmark where time != -1 and category = 1 GROUP BY type"); $pic_all_average_cdn = $all_cdn[0]['sum'] / $all_cdn[0]['id']; $zip_all_average_cdn = $all_cdn[1]['sum'] / $all_cdn[1]['id']; $api_all_average_cdn = $all_cdn[2]['sum'] / $all_cdn[2]['id']; ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>国内服务器基准测试</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script type="text/javascript"> $(function () { $('#container_pic').highcharts({ chart: { type: 'areaspline' }, title: { text: '2M图片速度测试' }, //subtitle: { // text: '没有CDN加速国内访问速度' //}, xAxis: { type: 'datetime', labels: { formatter: function() { return Highcharts.dateFormat('%H:%M', this.value); } } }, yAxis: { title: { text: '访问速度' } }, tooltip: { shared: true, dateTimeLabelFormats:{ day: '%Y-%m-%d %H:%M' }, valueSuffix: 's' }, credits: { enabled: false }, plotOptions: { areaspline: { fillOpacity: 0.5 } }, series: [{ name: '无CDN加速', data: <?php echo $pic;?> },{ name: '有CDN加速', data: <?php echo $pic_cdn;?> }] }); $('#container_zip').highcharts({ chart: { type: 'areaspline' }, title: { text: '12M离线包速度测试' }, //subtitle: { // text: '没有CDN加速国内访问速度' //}, xAxis: { type: 'datetime', labels: { formatter: function() { return Highcharts.dateFormat('%H:%M', this.value); } } }, yAxis: { title: { text: '访问速度' } }, tooltip: { shared: true, dateTimeLabelFormats:{ day: '%Y-%m-%d %H:%M' }, valueSuffix: 's' }, credits: { enabled: false }, plotOptions: { areaspline: { fillOpacity: 0.5 } }, series: [{ name: '无CDN加速', data: <?php echo $zip;?> },{ name: '有CDN加速', data: <?php echo $zip_cdn;?> }] }); $('#container_api').highcharts({ chart: { type: 'areaspline' }, title: { text: 'API接口速度测试' }, //subtitle: { // text: '没有CDN加速国内访问速度' //}, xAxis: { type: 'datetime', labels: { formatter: function() { return Highcharts.dateFormat('%H:%M', this.value); } } }, yAxis: { title: { text: '访问速度' } }, tooltip: { shared: true, dateTimeLabelFormats:{ day: '%Y-%m-%d %H:%M' }, valueSuffix: 's' }, credits: { enabled: false }, plotOptions: { areaspline: { fillOpacity: 0.5 } }, series: [{ name: '无CDN加速', data: <?php echo $api;?> },{ name: '有CDN加速', data: <?php echo $api_cdn;?> }] }); }); </script> </head> <body> <div id="container_pic" style="min-width: 310px; height: 400px; margin: 0 auto"></div> <br /> <div id="container_zip" style="min-width: 310px; height: 400px; margin: 0 auto"></div> <br /> <div id="container_api" style="min-width: 310px; height: 400px; margin: 0 auto"></div> <br /> <hr> <h1 style="text-align:center">无CDN访问速度</h1> <hr> <div style="margin-top:20px;"> <h2>访问2M图片最近一小时内平均速度为:<?php echo $pic_average;?>s</h2> <h2>访问12M离线包最近一小时内平均速度为:<?php echo $zip_average;?>s</h2> <h2>访问api接口最近一小时内平均速度为:<?php echo $api_average;?>s</h2> </div> <div style="margin-top:30px;"> <h2>访问2M图片平均速度为:<?php echo $pic_all_average;?>s</h2> <h2>访问12M离线包平均速度为:<?php echo $zip_all_average;?>s</h2> <h2>访问api接口平均速度为:<?php echo $api_all_average;?>s</h2> </div> <hr> <h1 style="text-align:center">有CDN访问速度</h1> <hr> <div style="margin-top:20px;"> <h2>访问2M图片最近一小时内平均速度为:<?php echo $pic_average_cdn;?>s</h2> <h2>访问12M离线包最近一小时内平均速度为:<?php echo $zip_average_cdn;?>s</h2> <h2>访问api接口最近一小时内平均速度为:<?php echo $api_average_cdn;?>s</h2> </div> <div style="margin-top:30px;"> <h2>访问2M图片平均速度为:<?php echo $pic_all_average_cdn;?>s</h2> <h2>访问12M离线包平均速度为:<?php echo $zip_all_average_cdn;?>s</h2> <h2>访问api接口平均速度为:<?php echo $api_all_average_cdn;?>s</h2> </div> </body> <script src="js/highcharts.js"></script> <script src="js/modules/exporting.js"></script> </html>数据库结构:
CREATE TABLE `benchmark` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `time` float NOT NULL, `type` tinyint(3) unsigned NOT NULL COMMENT '1:图片 2:zip 3:api', `category` tinyint(3) unsigned NOT NULL COMMENT '1:cdn 2:无cdn', `create_time` int(10) unsigned NOT NULL, `item` tinyint(3) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=27202 DEFAULT CHARSET=utf8;