思考
使用 Go 和 配置合理(框架主流)的 PHP 进行相同功能的实现,性能差距是数量级 的表现,当然在考虑绝大数的业务场景,使用 PHP 还是很推荐的,毕竟 array、框架的工具包真的太好用了!而如果是针对前台应用,尤其是高并发的场景下我想还是要慎重选择,当然 php 切换 swoole、workerman 框架会有质的飞跃,只是从当前的就业行情来看,多掌握下技能才是好的,毕竟现在的 PHP 的薪资是存在上升空间的。
准备工作
ab 压测工具
Go:
- 版本:1.19.4
- 框架:无
- 是否使用 Mysql 连接池: 有, 最大连接数为 100 相关代码
- 日志:是, 使用 seelog
PHP:
- 版本:8.1.15
- 框架:Yii2 2.0.47
- 缓存:开启 opcache、jit 配置
- FastFpm:dynamic 模式, 最大进程数 :64 (内存已经 150MB,而 Go 才 2MB, 我们这边 k8s 配置 1核2g)
- 日志:是, 使用 Yii logger
PHP opcache 配置如下 (代码不刷新,强制缓存)
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=192
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
# 组合使用, 若为 1 则在 revalidate_freq 时间内刷新代码
opcache.validate_timestamps=0
# opcache.revalidate_freq=60
; jit配置
opcache.jit=true
opcache.jit_buffer_size=64M
pm = dynamic
pm.max_children = 64
pm.start_servers = 32
pm.min_spare_servers = 16
pm.max_spare_servers = 64
测试方案
- QPS 20、 50、 100、 200 的情况下分别压测对应程序,看对应相应时间和分位值;
- 内存对比,放弃(不具备可比性)
测试结果
总数为: 1000
QPS | GO | PHP | 备注 |
---|---|---|---|
20 | QPS: 798.01 AVG:25.062 ms | QPS: 99.98 AVG:200.030 ms | PHP 主要慢于 DB 自身的连接创建,以及语言本身 |
50 | QPS: 1593.46 AVG:31.378 ms | QPS: 129.75 AVG:385.357 ms | Go QPS 提升是因为连接开始复用了 |
100 | QPS: 1387.81 AVG:72.056 ms | QPS: 121.31 AVG:824.302 ms | 平均耗时增加是由于数据库压力, 而 PHP 因为 FPM 的进程销毁&创建,也开始增大接口压力(当然可以配置常驻,当前是 32) |
200 | QPS: 1355.24 AVG:147.575 ms | QPS: 118.41 AVG:1689.022 ms | GO 的数据库连接数跑满了,所以需要等待,所以平均相应时间变长,而 PHP 是 FPM 最大 64个,从而限制并发上限 |
相关截图如下(左边 Go、右边 PHP)
tips
相关命令和参数说明
# 查询当前 php-fpm 进程数
ps -ef |grep "php-fpm"|grep "pool"|wc -l
# 查询内存占用
free -m
PHP Opcache
启用 OpCache,并在命令行模式下启用OpCache。这可以通过设置 opcache.enable 和 opcache.enable_cli 参数为1来实现。
调整内存消耗量以适应服务器的硬件配置。通常情况下,建议将opcache.memory_consumption设置为128MB或更高。
增加字符串缓冲区的大小,可以通过设置 opcache.interned_strings_buffer参数为16MB或更高来实现。
提高可加速的脚本文件数量的最大值,可以通过设置opcache.max_accelerated_files参数为4000或更高来实现。
关闭时间戳验证,可以通过将opcache.validate_timestamps参数设置为0来实现。
设置重新验证缓存中的文件的时间间隔,可以通过设置opcache.revalidate_freq参数为60秒或更高来实现。
启用快速关闭,可以通过将opcache.fast_shutdown参数设置为1来实现。
允许脚本覆盖缓存文件,可以通过将opcache.enable_file_override参数设置为1来实现。
在黑名单中列出禁止缓存的文件,可以通过设置opcache.blacklist_filename参数来实现。这可以避免将不应被缓存的文件加入缓存。
设置错误日志文件路径,可以通过设置opcache.error_log参数来实现。这可以帮助您快速发现和修复潜在的问题。
ab 常用参数说明
-n:指定总请求数。例如,-n 1000表示发出1000个请求。
-c:指定并发请求数。例如,-c 10表示同时发出10个请求。
-t:指定测试持续时间,单位为秒。例如,-t 60表示测试持续60秒。
-k:启用HTTP KeepAlive功能,即在一次TCP连接中处理多个HTTP请求。默认情况下,ab在每个请求之间关闭连接。
-p:指定包含POST数据的文件。例如,-p postdata.txt表示从postdata.txt文件中读取POST数据。
-H:指定请求头。例如,-H "Accept-Encoding: gzip, deflate"表示在请求头中设置Accept-Encoding字段。
-A:指定HTTP认证信息。例如,-A "username:password"表示使用基本的HTTP认证。
-s:指定测试期间等待服务器响应的最大时间,单位为秒。例如,-s 10表示等待服务器响应的最大时间为10秒。
-v:输出详细的调试信息,包括请求和响应头。
-V:输出版本信息。
ab 工具返回结果解释
Benchmarking www.baidu.com (be patient).....done
Server Software: Apache // web 服务软件名称
Server Hostname: www.baidu.com // 请求域名
Server Port: 80 // 请求端口
Document Path: /a // 请求路径(get 参数可以携带参数)
Document Length: 199 bytes // 文档字节
Concurrency Level: 20 // 并发数 -c 控制
Time taken for tests: 1.054 seconds // 任务请求耗时
Complete requests: 100 // 任务请求完成数量
Failed requests: 0 // 任务失败请求数量
Non-2xx responses: 100 // HTTP 码非 200 数量
Total transferred: 34400 bytes // 相应字符数
HTML transferred: 19900 bytes //
Requests per second: 94.86 [#/sec] (mean) // 平均每秒请求数
Time per request: 210.841 [ms] (mean) // 批次平均耗时
Time per request: 10.542 [ms] (mean, across all concurrent requests) // 单个请求的平均耗时 (基本等于 自身 * 并发数, 因为并发其实是 cpu 时间片轮询的)
Transfer rate: 31.87 [Kbytes/sec] received // 每秒字节数
Connection Times (ms)
min mean[+/-sd] median max // 最小 平均 中位数 最大
Connect: 8 10 1.1 10 16
Processing: 11 178 48.1 196 208
Waiting: 10 115 56.0 114 205
Total: 21 188 48.2 206 218
Percentage of the requests served within a certain time (ms) // 看分位情况,避免出现极大值
50% 206
66% 208
75% 209
80% 213
90% 216
95% 217
98% 217
99% 218
100% 218 (longest request)