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

2017-07-11 提问
1 个回答
0

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

该答案已被忽略,原因:

撰写答案

推广链接