ab压测过程中出现502及操作数据库失败

发布于 2022-09-05 04:34:45 字数 2904 浏览 30 评论 0

环境

  • 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个.

clipboard.png

可以看出失败是因为没有可用的fpm导致的

所以问题来了:

但是我不是开了300个fpm worker进程么?为什么还会出现502?

操作数据库

    function mysql_test()
    {
        $mysql = new mysqli();
        $mysql->query('insert into xxx("val") values("123")');
        $mysql->close();
    }

偶尔会出现这种报错
clipboard.png
google了一下,似乎是apache早期的版本会存在的问题,很早就修复了(一脸懵逼)...

继续测,好不容易没有返回上面的报错了(出现概率还是挺高的,有大神知道这是为啥吗?)

clipboard.png
可以看到,failed requests的数量是759个,查了下访问日志,都是200.
再加上网上有说failed requests中关于length的错误可以忽略,我心中一喜,卧槽,这是都成功了?于是我去看了眼数据库,共9241条记录,好吧,白开心了,刚才那些请求虽然返回了200,但实际上都是失败了的
但是想了下,刚刚写文件只有几十个,这改了数据库怎么就这么多了这么多?问题应该是出在数据库上了。查了下数据库连接数show variables like 'max_connections';只有151,然后默默的把它改到1000,再试
clipboard.png
failed requests变成2个了,看了下数据库里的记录,9998,这里是可以说通的。

但是这2个错误是怎么来的?我有观察ab过程中mysql的连接数mysqladmin -i1 status,最大的连接数不超过200。

我的问题

  1. fpm的worker进程本身是单线程的,它一次只会处理一个请求,只有在当前请求处理完了之后再去"抢占"外部的请求,就这个接口的响应速度和c200的并发量,似乎不应该出现502才对啊?是我哪里理解出错了吗?

  2. 为什么还会频繁存在apr_socket_connect() operation already in progress (37)这个报错?

  3. 改成数据库连接之后那2个失败的请求可能是怎么来的?还有最开始的时候,数据库连接数超过max_connections导致无法连接数据库的时候,为什么返回码还是200?(这里需要我代码里捕获异常吗?)

  4. 有什么提高qps的办法吗?

补充

最后吹一波swoole,同样的代码(没有复用数据库连接)去执行百分百完成而且qps很高。见下图:

clipboard.png

clipboard.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ペ泪落弦音 2022-09-12 04:34:45

哇咔咔,我找了半天的问题,终于发现你,一样的吐血。问一句,max_connections与show processlist那个连接有什么区别,虽然我1000并发,但是我show processlist却只有几个连接,所以我就一直没有管max_connections

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文