最近的发现
在我尝试过的所有其他事情中,我用自定义 JavaScript 替换了我的 JMeter 配置文件,该 JavaScript 在无限循环中依次访问我的每个 API 端点,然后在不同的浏览器(一个 Firefox、一个 Chrome、一个 Safari)中并行运行这个脚本 -尝试排除与来自同一来源的所有连接相关的问题(相同的用户代理、相同的 cookie、相同的会话 ID 等)
当我这样做时,我注意到我所有的问题都消失了。查询并行运行,应用程序的响应速度比 JMeter 让您相信的要快得多
在我看来,JMeter 将序列化请求似乎是不可能的,因为它是负载测试的事实上的标准。所以我开始尝试重现这种行为
为了重新创建 JMeter,我创建了以下两个 PHP 脚本,它们(希望)模拟了我的 Yii 应用程序:
慢.php
<?php
session_start();
$_SESSION['some'] = 'value';
// Yii is calling session_write_close() almost immediately after
// the session is initialized, but to try and exacerbate issues,
// I've commented it out:
// session_write_close();
$dsn = "mysql:host=localhost;dbname=platypus;unix_socket=/tmp/mysql.sock";
$pdo = new PDO($dsn, "user", "password");
// Yii was using whatever the default persistence behavior was,
// but to try and exacerbate issues I set this flag:
$pdo->setAttribute(PDO::ATTR_PERSISTENT, true);
// Simulate a query running for 1 second by issuing a 1-second sleep
$pdo->query("DO SLEEP(1)");
echo "Done";
快速.php
<?php
session_start();
$_SESSION['some'] = 'value';
$dsn = "mysql:host=localhost;dbname=platypus;unix_socket=/tmp/mysql.sock";
$pdo = new PDO($dsn, "user", "password");
$pdo->setAttribute(PDO::ATTR_PERSISTENT, true);
// Simulate a query running for 0.1 seconds
$pdo->query("DO SLEEP(0.1)");
echo "Done";
针对这两个新端点运行 JMeter,没有请求序列化。一切都是并行的。即使我扩展到 3、4 和 5 个线程,fast.php 总是在 100-150 毫秒内返回,而 slow.php 总是在 1000-1050 毫秒内返回。我能够看到事情在 11 个线程崩溃,但那是因为我超过了 PHP 中的工作线程数
所以总结一下:
该问题仅在使用 JMeter 分析我的 API 时出现,并且不是应用程序本身固有的
这个问题不仅仅是一个 JMeter 错误,而是与我的应用程序或 Yii 1.1 相关联
我试过但无法提出最低限度的复制案例
尽管在使用其他工具进行分析时不存在该问题,但很多人做出了回应并提供了很多有用的信息:
避免 PHP 中的持久连接(可能导致多个请求共享一个连接,可能不会)
session_write_close()
通过尽早调用来避免会话锁定
确保您有足够的 PHP 工作线程来处理同时连接的数量
MySQL 完全支持并行请求(如果硬件可以处理的话)
警惕表锁定(任何带有UPDATE
语句的事务都可能锁定表)
MyISAM 执行表级锁定而不是行级锁定
阿晨1998
慕码人2483693
慕码人8056858
UYOU