项目上线前要做压测,好激动,这是站主第一次正式的做上线前的压测。
根据以往经验,单php执行的话,速度不会慢,压测前,想着应该能清请松松压过去的。
实际上了测试环境后,压测才发现,与想想的十万八千里,只能去做优化,然而,再次查看一遍代码流程,基本所有操作都是业务的最小单元了,没找到太值得修改优化的点。简单的改动下,再次压测,效果不怎么理想。
怎么办?一个现实的问题。将架构组的同学拉进来帮忙,然后自己将每一个代码小单元前后加上时间(microtime(true)),输出到日志,压测完将日志拿,然后写代码分析日志,最后发现两个大的时间消耗点在两个外部接口的请求上。
ok,找到问题点下面就好说了。框架组的意思,是压测时间的增长是一个逐渐积累的过程。但是开发组的人对整个流程认识较浅。没有很明白框架组童鞋给出的意思。本着非我族类,其心必异的想法(是你们的接口,拖慢了io,那你们优化去把),把压力推到了提供接口的开发人员那边。
但是接口提供方的接口压测结果却是很理想的。也没什么可优化的点了。没办法,公司相关技术人员一起讨论。先是要把问题想明白了,到底是不是接口问题。通过运维对整个流程的介绍,最后发现,问题出在nginx 和 php 的交互上,nginx 把大量的请求发送到php,php处理不过来,造成了排队。
最后,通过加缓存当方式解决了问题。
总结:
1.php-fpm 是进程,每一次求情,对与php来说,是开启一个线程(单线程),单个php线程的处理时间,决定php-fpm进程的效率(当php-fpm设定最大开启2个,nginx同一时间转来请求是100个,假设每个线程需要执行500毫秒,则认定php每秒可处理4个请求,其他请求要么排队,要么因超时被抛弃,被抛弃的就是我们常见的502)。php-fpm进程数可以调多,多了会对服务器cpu和内存产生压力(多核cpu协同调度的流程暂时还不是太清楚,先跳过)。
2.php链接redis,可开启长链接($redis->pconnect()),链接句柄保存在php-fpm中,开启长连接后,close()方法可以认为没作用了,想要消除句柄,可以用unset();mysql 同样可以开启长链接。长链接,普通链接,单例 三者的区别:长连接是放在php-fpm中的,正常情况下,生命周期和php-fpm的生命周期是一样的。普通链接随线程的结束而释放。单例的意义在于整个线程中仅进行一句柄请求。
3.php fgets():函数。是上当前系统(应该是内从中吧)中读取数据,如果如果读取的资源是来自于网络,则会先等待网络资源传输完毕后,再进行读取。一下信息并不全面,也不一定正确,单作为phper这么理解应该没问题。
fsockopen() // 三次握手建立网络链接 fwrite() // 将求情信息发送到输出缓冲区,由系统处理后发送数据包 fgets() // 等待对方网络数据包到达缓冲区,然后从缓冲区读取数据
4.我们整个架构中存在 kong服务 , 对他了解还不够深刻,也没明显看到他的存在作用(当前的了解是dns将域名解析到kong,kong负责“域名转发?”)。但是知道当php-fpm进程开大后,他就会成为新的瓶颈。。汗!!!
5.注意点:当项目上线后,随着数据库数据量的增加,数据查询应该会成为新的瓶颈点,到时可考虑使用静态化,添加cdn等方式解决,解决方法很多,具体怎么解决待定,反正由巨人在顶着天^_^!
推荐两个好用的压测工具:
ab 和 webbench :
ab
安装ab
yum -y install httpd-tools
按照20并发,进行 100 次的请求
ab -n 100 -c 20 http://192.168.0.2/ -c 20 即:每次并发20个 -n 100 即:共发送100个请求
返回结果参考
Concurrency Level: 100 // 并发等级 100并发 Time taken for tests: 9.366 seconds // 总请求时长 Complete requests: 1000 // 总请求次数 Requests per second: 106.77 [#/sec] (mean) // 吞吐量
webbench
安装webbench
wget http://home.tiscali.cz/cz210552/distfiles/webbench-1.5.tar.gz tar zxvf webbench-1.5.tar.gz cd webbench-1.5 make && make install
按照20并发,进行10秒钟请求
webbench -c 20 -t 10 http://192.168.0.2/ -c 20 即:每次并发20个 -t 10 即:请求时长为10秒
返回结果参考
Speed=44616 pages/min, 287068 bytes/sec. // 分析:每秒钟响应请求数:Speed=44616 pages/min,每秒钟传输数据量287068 bytes/sec Requests: 7436 susceed, 0 failed. // 请求成功 7436 次 ,请求失败 0 次