作者:陈雅洁惠真慧瑋 | 来源:互联网 | 2023-07-14 12:11
环境
压测
1
| ab -n10000 -c200 -r -k http://url |
只写文件
1 2 3 4
| 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](https://img.php1.cn/3cd4a/1eebe/cd5/5b97d3b808d031e2.webp)
可以看出失败是因为没有可用的fpm导致的
所以问题来了:
但是我不是开了300个fpm worker进程么?为什么还会出现502?
操作数据库
1 2 3 4 5 6
| function mysql_test()
{
$mysql = new mysqli();
$mysql->query('insert into xxx("val") values("123")');
$mysql->close();
} |
偶尔会出现这种报错
![clipboard.png](https://img.php1.cn/3cd4a/1eebe/cd5/ed19db63ee478b98.png)
google了一下,似乎是apache早期的版本会存在的问题,很早就修复了(一脸懵逼)...
继续测,好不容易没有返回上面的报错了(出现概率还是挺高的,有大神知道这是为啥吗?)
![clipboard.png](https://img.php1.cn/3cd4a/189d8/b64/5b34b53b79a39fdd.jpeg)
可以看到,failed requests的数量是759个,查了下访问日志,都是200.
再加上网上有说failed requests中关于length的错误可以忽略,我心中一喜,卧槽,这是都成功了?于是我去看了眼数据库,共9241条记录,好吧,白开心了,刚才那些请求虽然返回了200,但实际上都是失败了的。
但是想了下,刚刚写文件只有几十个,这改了数据库怎么就这么多了这么多?问题应该是出在数据库上了。查了下数据库连接数
1
| show variables like 'max_connections'; |
只有151,然后默默的把它改到1000,再试
![clipboard.png](https://img.php1.cn/3cd4a/1eebe/cd5/ed19db63ee478b98.png)
failed requests变成2个了,看了下数据库里的记录,9998,这里是可以说通的。
但是这2个错误是怎么来的?我有观察ab过程中mysql的连接数
,最大的连接数不超过200。
我的问题
fpm的worker进程本身是单线程的,它一次只会处理一个请求,只有在当前请求处理完了之后再去"抢占"外部的请求,就这个接口的响应速度和c200的并发量,似乎不应该出现502才对啊?是我哪里理解出错了吗?
为什么还会频繁存在
1
| apr_socket_connect() operation already in progress (37) |
这个报错?
改成数据库连接之后那2个失败的请求可能是怎么来的?还有最开始的时候,数据库连接数超过max_connections导致无法连接数据库的时候,为什么返回码还是200?(这里需要我代码里捕获异常吗?)
有什么提高qps的办法吗?
补充
最后吹一波swoole,同样的代码(没有复用数据库连接)去执行百分百完成而且qps很高。见下图:
![clipboard.png](https://img.php1.cn/3cd4a/1eebe/cd5/e88efe5b0a13a7fa.webp)
![clipboard.png](https://img.php1.cn/3cd4a/1eebe/cd5/21e585a7e21fc7dc.png)