如何对php/mysql站点进行基准测试

如何对php/mysql站点进行基准测试,php,mysql,benchmarking,load-testing,Php,Mysql,Benchmarking,Load Testing,我想知道如何对php/mysql站点进行基准测试 我们已经有一个web应用程序几乎完成并准备上线,我们知道有多少人将在一年内使用它,但绝对不知道平均用户需要多少带宽,他们在数据库上消耗了多少时间等等。我们需要确定要购买的正确服务器 是否有服务器端linux可以监控每个用户的这些统计数据?这样我们就可以得到这些数据并进行推断 如果我完全错了,请让我知道,但我相信这是一个新的网络应用程序的频繁活动 编辑:我可能要求提供不正确的信息。我们可以看到数据库查询需要多长时间以及加载页面需要多长时间,但不知道

我想知道如何对php/mysql站点进行基准测试

我们已经有一个web应用程序几乎完成并准备上线,我们知道有多少人将在一年内使用它,但绝对不知道平均用户需要多少带宽,他们在数据库上消耗了多少时间等等。我们需要确定要购买的正确服务器

是否有服务器端linux可以监控每个用户的这些统计数据?这样我们就可以得到这些数据并进行推断

如果我完全错了,请让我知道,但我相信这是一个新的网络应用程序的频繁活动

编辑:我可能要求提供不正确的信息。我们可以看到数据库查询需要多长时间以及加载页面需要多长时间,但不知道服务器上会加载什么。我要问的问题是,我们能否同时平均处理100个用户…1000个?需要什么类型的服务器才能满足一百万用户的需求。等等


谢谢您的帮助。

我对基准测试工具没有任何经验,但在某些情况下,我创建了一个简单的表,其中包含
id
ipaddress
parsetime
查询
。只要在每次刷新或调用页面时插入新行(在ajax情况下)。然后分析一周/月/季度/年收集的数据。这不是你喜欢的情况,而是一种在短时间内获得统计数据的简单方法

PHP基准测试的一些结果:

除非您使用的是,否则DB查询可能是应用程序中最慢的部分

我所做的监视是测量数据库抽象对象中每个查询的执行时间。然后,对于每一个耗时超过X毫秒的查询(填写您自己的X),我会在我的查询日志文件中写一行,标识PHP脚本文件和查询出现的行号(使用
debug_backtrace()
查找该信息)以及其他相关上下文数据(例如用户身份、日期时间等)

此日志文件可在以后对各种信息进行统计分析

例如,您可以找到哪些查询占用的总时间最大(与服务器负载相关)。或者哪些是最慢的(与用户体验相关)。或者哪个用户加载系统最多(可能是滥用或机器人)


我还绘制了帕累托图,以确定在哪里进行查询优化效果最好。

最重要的是,您需要定义您想要的性能:您总是可以找到需要优化的区域。但是,将响应时间从750ms提高到650ms可能不值得花时间

正如fsb所说,您的瓶颈可能是数据库查询。然而,我还要规定,瓶颈并不总是(甚至不可能)在您认为的地方。我建议先阅读,然后对你的网站做一个全面的测试

如果它是您的应用程序,请使用xdebug评测PHP代码。然后使用WinCacheGrind或KCacheGrind分析输出。这可能会让你大吃一惊


为了解决数据库问题,它非常特定于数据库。对于MySQL,我打开慢速查询日志,记录不使用索引的查询,启用查询日志,并使用Maatkit之类的工具包分析查询并找到瓶颈。

您可以使用ApacheBench工具(ab,通常是apache web服务器包的一部分)对脚本进行压力测试(10个客户端的1k请求=ab-c 10-n 1000),你怀疑它可能足够慢。 它将显示响应时间的分布(在90%的情况下,请求处理时间不到200毫秒)

然后,您还可以获取由该特定脚本执行的SQL查询,并为它们执行“解释计划”,以大致了解当表中的记录将增加10-100-10万亿倍时,SQL查询将如何降级


关于它可以为多少用户提供服务-您可以使用您最喜欢的浏览器,模拟典型的用户访问,访问日志文件并对发送的字节(日志行中的最后一个数字之一)求和。例如,它是5kb文本/html+50kb png/jpg/etc.=每次用户访问55kb。加上标题/等等,比如每次访问60kb*1m=每天60gb的流量。你的带宽足够吗?(60gb/86.4ksec=700kb/sec)。

我发现一个非常有用的工具,它允许(最基本的)您将浏览器设置为使用jmeter作为代理,然后您在网站上四处漫游,它会记录您所做的一切

一旦您觉得这是对大多数网站的一个不错的测试,您就可以将该测试保存在jmeter中,并告诉它使用设置的线程数和每个线程的循环数来运行测试,以模拟网站上的负载

例如,您可以运行50个客户端,每个客户端运行测试计划10次

然后,您可以上下调整数字,以查看它对站点的性能影响,它会为您绘制响应时间图


这使您可以调整不同的参数,尝试不同的缓存策略,并检查这些更改对现实世界的影响。

我最近开发了一个PHP组件,可以轻松地为您的基准测试进行测试并生成报告。我还发表了一篇关于基准测试重要性的文章,我指出了测试的重要性,因为不测试可能会对web服务器造成压力。基准测试非常重要,但我认为,在当今这个时代,人们往往忘记了这一点,而事实上,基准测试应该放在检查表的顶部。Bug检查、安全检查,然后是基准测试

按这个顺序

-我开发的框架 -我写的那篇文章试试看:

<?php
/**
 * Created by PhpStorm.
 * User: NEO
 * Date: 9/18/2016
 * Time: 10:57 AM
 */

/**
 * PHP Script to benchmark PHP and MySQL-Server
 *
 * inspired by / thanks to:
 * - www.php-benchmark-script.com  (Alessandro Torrisi)
 * - www.webdesign-informatik.de
 *
 * @author odan
 * @license MIT
 */
// -----------------------------------------------------------------------------
// Setup
// -----------------------------------------------------------------------------
set_time_limit(120); // 2 minutes
$options = array();
// Optional: mysql performance test
$options['db.host'] = '127.0.0.1';
$options['db.user'] = 'root';
$options['db.pw'] = '';
$options['db.name'] = 'bache3';
// -----------------------------------------------------------------------------
// Main
// -----------------------------------------------------------------------------
// check performance
$benchmarkResult = test_benchmark($options);
// html output
echo "<!DOCTYPE html>\n<html><head>\n";
echo "<style>
    table {
        color: #333; /* Lighten up font color */
        font-family: Helvetica, Arial, sans-serif; /* Nicer font */
        width: 640px;
        border-collapse:
        collapse; border-spacing: 0;
    }
    td, th {
        border: 1px solid #CCC; height: 30px;
    } /* Make cells a bit taller */
    th {
        background: #F3F3F3; /* Light grey background */
        font-weight: bold; /* Make sure they're bold */
    }
    td {
        background: #FAFAFA; /* Lighter grey background */
    }
    </style>
    </head>
    <body>";
echo array_to_html($benchmarkResult);
echo "\n</body></html>";
exit;
// -----------------------------------------------------------------------------
// Benchmark functions
// -----------------------------------------------------------------------------
function test_benchmark($settings)
{
    $timeStart = microtime(true);
    $result = array();
    $result['version'] = '1.1';
    $result['sysinfo']['time'] = date("Y-m-d H:i:s");
    $result['sysinfo']['php_version'] = PHP_VERSION;
    $result['sysinfo']['platform'] = PHP_OS;
    $result['sysinfo']['server_name'] = $_SERVER['SERVER_NAME'];
    $result['sysinfo']['server_addr'] = $_SERVER['SERVER_ADDR'];
    test_math($result);
    test_string($result);
    test_loops($result);
    test_ifelse($result);
    if (isset($settings['db.host'])) {
        test_mysql($result, $settings);
    }
    $result['total'] = timer_diff($timeStart);
    return $result;
}
function test_math(&$result, $count = 99999)
{
    $timeStart = microtime(true);
    $mathFunctions = array("abs", "acos", "asin", "atan", "bindec", "floor", "exp", "sin", "tan", "pi", "is_finite", "is_nan", "sqrt");
    for ($i = 0; $i < $count; $i++) {
        foreach ($mathFunctions as $function) {
            call_user_func_array($function, array($i));
        }
    }
    $result['benchmark']['math'] = timer_diff($timeStart);
}
function test_string(&$result, $count = 99999)
{
    $timeStart = microtime(true);
    $stringFunctions = array("addslashes", "chunk_split", "metaphone", "strip_tags", "md5", "sha1", "strtoupper", "strtolower", "strrev", "strlen", "soundex", "ord");
    $string = 'the quick brown fox jumps over the lazy dog';
    for ($i = 0; $i < $count; $i++) {
        foreach ($stringFunctions as $function) {
            call_user_func_array($function, array($string));
        }
    }
    $result['benchmark']['string'] = timer_diff($timeStart);
}
function test_loops(&$result, $count = 999999)
{
    $timeStart = microtime(true);
    for ($i = 0; $i < $count; ++$i) {
    }
    $i = 0;
    while ($i < $count) {
        ++$i;
    }
    $result['benchmark']['loops'] = timer_diff($timeStart);
}
function test_ifelse(&$result, $count = 999999)
{
    $timeStart = microtime(true);
    for ($i = 0; $i < $count; $i++) {
        if ($i == -1) {
        } elseif ($i == -2) {
        } else if ($i == -3) {
        }
    }
    $result['benchmark']['ifelse'] = timer_diff($timeStart);
}
function test_mysql(&$result, $settings)
{
    $timeStart = microtime(true);
    $link = mysqli_connect($settings['db.host'], $settings['db.user'], $settings['db.pw']);
    $result['benchmark']['mysql']['connect'] = timer_diff($timeStart);
    //$arr_return['sysinfo']['mysql_version'] = '';
    mysqli_select_db($link, $settings['db.name']);
    $result['benchmark']['mysql']['select_db'] = timer_diff($timeStart);
    $dbResult = mysqli_query($link, 'SELECT VERSION() as version;');
    $arr_row = mysqli_fetch_array($dbResult);
    $result['sysinfo']['mysql_version'] = $arr_row['version'];
    $result['benchmark']['mysql']['query_version'] = timer_diff($timeStart);
    $query = "SELECT BENCHMARK(1000000,ENCODE('hello',RAND()));";
    $dbResult = mysqli_query($link, $query);
    $result['benchmark']['mysql']['query_benchmark'] = timer_diff($timeStart);
    mysqli_close($link);
    $result['benchmark']['mysql']['total'] = timer_diff($timeStart);
    return $result;
}
function timer_diff($timeStart)
{
    return number_format(microtime(true) - $timeStart, 3);
}
function array_to_html($array)
{
    $result = '';
    if (is_array($array)) {
        $result .= '<table>';
        foreach ($array as $k => $v) {
            $result .= "\n<tr><td>";
            $result .= '<strong>' . htmlentities($k) . "</strong></td><td>";
            $result .= array_to_html($v);
            $result .= "</td></tr>";
        }
        $result .= "\n</table>";
    } else {
        $result = htmlentities($array);
    }
    return $result;
}

是的,我想我正在寻找应用程序之外的东西来跟踪它的功能。我已经更新了我的答案并提供了一个链接,希望它能进一步帮助你。为什么要投反对票?给出答案的人能解释这个答案有什么问题吗?回答得好!我要在我正在做的一些更大的项目中实现这一点!有限公司