ab压测过程中出现502及操作数据库失败
环境
fpm(static、pm.max_children=300, max_request=0)
apache(2.4.24)
php7(7.0.7)
macbook(Sierra 10.12.5、2核心、8G内存)
压测
ab -n10000 -c200 -r -k http://url
只写文件
function write_to_file()
{
file_put_contents('a.txt', time().PHP_EOL, FILE_APPEND);
}
结果:每次大概会有n(几十个)个failed requests,查看了a.txt里的记录数也是(10000-n),统计了下nginx的访问日志,最近1W个记录里面502的个数也是n个.
可以看出失败是因为没有可用的fpm导致的
所以问题来了:
但是我不是开了300个fpm worker进程么?为什么还会出现502?
操作数据库
function mysql_test()
{
$mysql = new mysqli();
$mysql->query('insert into xxx("val") values("123")');
$mysql->close();
}
偶尔会出现这种报错
google了一下,似乎是apache早期的版本会存在的问题,很早就修复了(一脸懵逼)...
继续测,好不容易没有返回上面的报错了(出现概率还是挺高的,有大神知道这是为啥吗?)
可以看到,failed requests的数量是759个,查了下访问日志,都是200.
再加上网上有说failed requests中关于length的错误可以忽略,我心中一喜,卧槽,这是都成功了?于是我去看了眼数据库,共9241条记录,好吧,白开心了,刚才那些请求虽然返回了200,但实际上都是失败了的。
但是想了下,刚刚写文件只有几十个,这改了数据库怎么就这么多了这么多?问题应该是出在数据库上了。查了下数据库连接数show variables like 'max_connections';
只有151,然后默默的把它改到1000,再试
failed requests变成2个了,看了下数据库里的记录,9998,这里是可以说通的。
但是这2个错误是怎么来的?我有观察ab过程中mysql的连接数
mysqladmin -i1 status
,最大的连接数不超过200。
我的问题
fpm的worker进程本身是单线程的,它一次只会处理一个请求,只有在当前请求处理完了之后再去"抢占"外部的请求,就这个接口的响应速度和c200的并发量,似乎不应该出现502才对啊?是我哪里理解出错了吗?
为什么还会频繁存在
apr_socket_connect() operation already in progress (37)
这个报错?改成数据库连接之后那2个失败的请求可能是怎么来的?还有最开始的时候,数据库连接数超过max_connections导致无法连接数据库的时候,为什么返回码还是200?(这里需要我代码里捕获异常吗?)
有什么提高qps的办法吗?
补充
最后吹一波swoole,同样的代码(没有复用数据库连接)去执行百分百完成而且qps很高。见下图:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哇咔咔,我找了半天的问题,终于发现你,一样的吐血。问一句,max_connections与show processlist那个连接有什么区别,虽然我1000并发,但是我show processlist却只有几个连接,所以我就一直没有管max_connections