1,使用 apache的ab工具进行高并发测试
找到apache的工具 (建议内网测试,排除网络延迟的原因)
按时间测试:测试url 100个线程(-c 100) 持续30秒(-t 30),使用get方式请求url("url"),并且将每次的请求都保存到当前目录下的p.txt文件内(-g p.txt),详细汇总保存到output.csv文件内(-e output.csv)
ab -e output.csv -g p.txt -c 100 -t 30 "http://www.web.com//api/api2/boundary?type=boundary&v=v11610074518437"按次数测试:测试1000次 请求(-n 1000)
ab -e output.csv -g p.txt -c 100 -n 1000 "http://www.web.com//api/api2/boundary?type=boundary&v=v11610074518437"
效果解读
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.web.com(be patient)
Finished 3427 requests (总请求数)
Server Software: nginx (服务器软件)
Server Hostname: www.web.com (目标域名)
Server Port: 80 (端口号)Document Path: /api/api2/boundary?type=boundary&v=v11610074518437 (测试的URL地址)
Document Length: 88 bytes (测试地址返回的大小)Concurrency Level: 100 (并发数)
Time taken for tests: 30.680 seconds (压测总消耗时长)
Complete requests: 3427 (压测请求总数)
Failed requests: 0 (失败请求数)
Total transferred: 1468896 bytes (传输的总数据量)
HTML transferred: 302016 bytes (HTML文档的总数据量)
Requests per second: 111.70 [#/sec] (mean) (平均每秒的请求数)
Time per request: 895.243 [ms] (mean) (所有用户请求的一次的平均时间,即100个用户请求一次的时间合计 后的平均值)
Time per request: 8.952 [ms] (mean, across all concurrent requests) (单个用户请求一次的平均时间)
Transfer rate: 46.76 [Kbytes/sec] received (传输速率,单位Kb/s)start 准备开始建立连接 connect 已经建立连接(并进入等待状态) endwrite 已送出 HTTP Request 指令 beginread 已收到 HTTP Response 的第一个 byte done 完成 HTTP 要求并中断连接
Connection Times (ms)
最小值 | 平均值 [+/-偏差值] | 中间值 | 最大值
min | mean [+/-sd] | median | max
Connect(连接数): 6 | 8 1.1 | 8 | 16 (从 start 到 connect 所花费的时间)
Processing(处理数): 822 | 862 16.8 | 862 | 1094 (从 connect 到 done 所花费的时间)
Waiting(等待数): 19 | 466 244.6 | 467 | 1051 (从 endwrite 到 beginread 所花费的时间)
Total(总数): 831 | 870 16.9 | 870 | 1103 (从 start 到 done 所花费的时间)Percentage of the requests served within a certain time (ms) (整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间,其中50%的用户响应时间小于870 毫秒,60% 的用户响应时间小于876 毫秒,最大的响应时间小于1103毫秒)
参考网:ab命令行解读
50% 870
66% 876
75% 881
80% 884
90% 893
95% 900
98% 904
99% 910
100% 1103 (longest request)(最长的一次请求时间)
2,Linux查看运行内存
linux输入命令:top
压测的时候发现MySQL运行内存激增,但我请求的代码并没有调用数据库,怀疑是使用的框架自带请求了数据库
3,使用MySQL获取查询日志
要查找框架初始化的时候进行了哪些数据库操作,那么首先就需要知道数据库哪些操作
-- 查看mysql记录到哪里
show variables like "%log_output%";-- 开启记录查询日志
set global general_log='on';-- 设置查询日志存储到表
set global log_output='table';-- 获取最近查询的20条记录
select event_time,argument from mysql.general_log
where argument like 'select%' or argument like 'SELECT%'
order by event_time desc limit 20;-- 获取指定时间内的100条 执行记录
select * from mysql.general_log where command_type='Execute' and event_time
between '2021-01-07 17:43:30' and '2021-01-07 17:43:49' limit 100;-- 关闭查询日志
set global general_log='off';-- 清空日志
truncate table mysql.general_log;
注:在MySQL最近的查询结果中 只需要找和自己项目相关的表和语句就行,其他语句是工具或者系统查询本身就会写入的语句
在日志记录里找到 程序初始化会执行的表后,那么就要找到在哪里执行 并且判断是否可控(即不修改框架代码的情况下删除不需要的sql执行)
4,代码定位
方法一:首先我们得需要指定 哪些类和这些sql语句内的表 相关,这里直接使用 vscode 的全局查找就可以了,然后使用 xdebug+qcachegrind 找到有调用的相关类和方法后 定位 相关代码。这种方法比较花费时间和精力,还需要一些运气 才能完全正确得定位,万不得已得情况下不推荐这种方法。
方法二:直接把项目初始化时候 执行了相关sql语句的表改名,让程序报错 定位 获取到 代码的位置。推荐这种方法,让代码认错。
确定了初始化代码运行的sql语句的位置后,就是优化减少不必要的数据库操作。这里依据项目情况而定。
5,计算服务器的并发理论值
优化了代码逻辑后,在不连接数据库的情况下,直接获取项目的接口数据,提出不必要的运行内容。2核4G的配置,请求一次得到 时间最小值是18ms,最大时间是 1913ms,要说这没问题肯定没人信
作为理论极限并发值,所以取最小值18ms作为响应时间,那么服务器极限一秒的并发处理量应该是 1000ms/18ms*2(服务器的核数) 约等于 111的请求数 。
理论最低并发值取 最长的接口请求的最小响应时间,这个测试比较复杂。
6,进行性能调优和优化配置
实际运行的时候,并发量都会低于 理论并发的极限值,如上面实际测试的并发值是 99.82
因为这次测试已经排除了MySQL的影响因素,所以问题的核心就在于 请求时 服务器并发处理的线程数
PHP:
这里我的php的运行模式配置为动态模式,对服务器的资源性价比高的使用方式。
nginx:
nginx这里的处理进程配置参考 nginx 进程数设置
mysql:
MySQL这里没有进行相关测试,不过建议按服务器配置进行优化
站点设置:
如非必要,关闭流量控制限制
程序设置:
关闭开发者模式,关闭xdebug,卸载没有使用的扩展
注:上诉测试结果是在外网测试的数据,准确测试应该要在内网进行测试,因为数据在网络传输的过程中,对服务端来说并不饱和,故并实际并发数据要比上述 的3倍。如果使用常驻内存的 swoole的话,相同的配置下 并发数是上述数据的 50倍。
EasySwoole 内网压测
[root@VM_0_15_centos ~]# ab -c 100 -t 30 "http://127.0.0.1:9601/home/test/test2"
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests
Server Software: EasySwoole
Server Hostname: 127.0.0.1
Server Port: 9601
Document Path: //home/test/test2
Document Length: 161 bytes
Concurrency Level: 100
Time taken for tests: 9.463 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Total transferred: 18450000 bytes
HTML transferred: 8050000 bytes
Requests per second: 5283.55 [#/sec] (mean)
Time per request: 18.927 [ms] (mean)
Time per request: 0.189 [ms] (mean, across all concurrent requests)
Transfer rate: 1903.94 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 2.3 3 22
Processing: 1 16 6.6 15 81
Waiting: 0 13 6.2 13 77
Total: 1 19 6.9 18 84
Percentage of the requests served within a certain time (ms)
50% 18
66% 21
75% 22
80% 23
90% 27
95% 30
98% 35
99% 39
100% 84 (longest request)