24

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

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

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

如果我完全错了,请告诉我,但我相信这是新网络应用程序的常见活动。

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

谢谢你的帮助。

4

7 回答 7

16

我觉得相当有用的一个工具是jmeter,它允许(最基本的)你将浏览器设置为使用 jmeter 作为代理,然后你在你的网站上四处游荡,它会记录你所做的一切。

一旦您对它对您的大部分网站的测试感到满意,您就可以将测试保存在 jmeter 中,并告诉它使用设定的线程数和每个线程的循环数来运行您的测试,以模拟您网站上的负载。

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

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

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

于 2009-12-03T01:18:00.357 回答
8

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

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

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

于 2009-12-02T23:18:59.223 回答
6

除非您使用重量级框架或类似的东西,否则数据库查询可能是您的应用程序中最慢的部分。

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

稍后可以对该日志文件进行统计分析以获取各种信息。

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

我还绘制了帕累托图来确定最适合在哪里花费我的查询优化工作。

于 2009-12-02T16:17:13.313 回答
2

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

正如 fsb 所说,您的瓶颈可能是您的数据库查询。但是,我还要规定,您的瓶颈并不总是(甚至可能)在您认为的位置。我建议先阅读 这篇文章,然后对您的网站进行全球测试。

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

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

于 2009-12-02T16:35:24.277 回答
1

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

以该顺序。

http://www.binpress.com/app/benchmark-testing-framework/534?ad=1229 - 我开发的框架 http://www.binpress.com/blog/2011/08/04/the- important-of-benchmark-testing/?ad=1229 - 我写的文章

于 2011-08-15T22:06:03.400 回答
1

尝试这个:

<?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;
}
于 2016-09-18T15:11:04.020 回答
0

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

PHP 基准测试的一些结果: http ://www.google.nl/search?hl=nl&source=hp&q=php+benchmark&meta=&aq=f&oq=

于 2009-12-02T16:00:50.810 回答