随着业务的迭代,服务器经常在业务高峰期时,cpu的使用率达到了100%,服务器开始报警,客户端开始出现大量卡顿。
对于我们只有5w日活直播平台,10台ucloud 8核、16g内存的服务器配置来说已经是相当高的配置了完全可以应对。
但是cpu100%的问题还是出现了,于是开始排查问题。首先找运维同事截取了业务高峰期服务器监控,如下图:
服务器 进程开始堆积 redis监控(自建)发现磁盘io、网络带宽、mysql、redis都是比较正常的,只有cpu100%,通过nginx监控查看到,单个业务机上每秒的qps还不到400个,php-fpm进程数是500个,php框架是slim3.4.2。
根据监控数据、加上以往经验推断出有两个原因导致:
1. php有大量的计算,业务逻辑不合理;
2. php在等待mysql或redis连接,占用着cpu不放;
这两点原因都指向一个地方“代码”,于是就请运维同事在生产环境把 xhprof监控搭建了起来。看完xhprof监控更能肯定自己的推断,监控如下图:
xhprof监控接口平均执行时间在300ms左右,而且还不是在业务高峰期,是不是很吓人。各位看官继续往下看,我们随便点进去一个请求:
一次接口请求,函数调用次数排名28941次函数调用,看到这些吓人的次数和函数名带有route, 立刻就明白导致cpu100%的问题所在和mysql,redis连接无关,那就是slim框架路由,直接上路由配置图康康:
slim入口index.phpinclude 了大量的路由配置上图:
将近4000个路由配置所以每当一个API请求过来时,index.php 加载所有路由配置文件,App.php map函数生成将近4000个Route对象(反正我们内存够用),放到Router->routes数组中。map函数除了创建Route对象还包括其他处理这也就导致为什么 preg_match函数会有28941调用,map具体执行请使用xdebug康康。
定位到问题所在,话不多说开始优化,如下图:
index.php优化后 某个路由文件将原来路由配置使用数组替代,通过数组key定位request路由,只创建请求需要的Route,不需要遍历再4000个路由了。相信到这里大家都能明白了,框架本身并没有太多问题,就看我们怎么用。
优化上线后经过几天的监控观看,cpu100%没有出现过,API响应时间提升了将近6倍,也为公司节省没必要的服务器开支。
网友评论