业务场景
因为摄像设备需要实时存储数据实现云播放,要求定时从5000+台设备同步数据到服务器存储数据索引数据,解析图片,推送通知。
服务器环境
系统:阿里云CentOs
硬件:4核,8G内存
软件环境:nginx+php7.2+mysql+nodejs(维持设备长链接)
问题总结
- 单秒并发请求多,平均每秒100+个请求量;
- 单个请求占用服务器资源过多,进程阻塞时间过长,涉及数据库事务处理、api请求调用,100个请求可能产生100个推送通知。
- mysql始终处于CPU、TPS高压线
- 服务器CPU高占用,高负载,且随着设备的增加,两指标也相应提高。导致服务器时而出现“503 请求不可达”,严重时系统宕机,附上服务器top图:
性能瓶颈分析
- mysql:mysql相关数据表数据量过亿;对应的sql查询没有正确使用到索引
- 代码:业务代码存在大事务,存在低效的遍历mysql查询
- 高IO消耗:api调用数量多且高频
优化方案
经过一段时间的分析与讨论,最终优化方案分为三步走
-
紧急方案
- 升级服务器硬件
4核升级G8核(当时8核依然不能满足过渡期,最后升级为24核)
8G内存升级到16G
msyql rds升级到8核16G - 服务降级
根据策略暂时缩减极光推送的请求量
- 升级服务器硬件
-
短期方案
- mysql
大事务拆成小事务
找出慢查询、索引优化 - 将多个推送请求集中起来,集中交给nodejs异步批量推送,nodejs只发送请求,不处理结果,这里用到redis的list和发布订阅
- 将高访问量接口分离出来,使用原生php实现业务,缩短框架本身初始化带来的性能消耗。
- mysql
落地效果
- 短期方案上线后,服务器cpu以及负载明显下降
-
mysql压力有所降低,仍有优化空间