项目背景:
一个通过微信网页访问在线答题的功能 ,目标用户覆盖江西全省大中小学生。
阿里云服务器性能:
CPU: 2核 内存:4 GB 带宽:3Mbps,环境: LAMP
已经完成的功能:
1. 微信授权
2. 随机筛选 30 道题输出
3. 前端页面单选的交互
4. 记录答案提交的数据(答对题目、时间)
5. 计算在同学校同年级的排名
考虑到的优化:
1. 不是每个人都是随机考题,考虑到参与人数众多,题库也才 50道题,50抽30,做相同的考题的几率还是挺高的,顺便就控制在一个时间周期内的考题一样,不重复那数据;所以就第一个用户访问获取到 30 道题后先得到考卷数据,存入本地文件,5分钟有效,超时重新生成考卷;
2. 静态文件都通过cdn服务访问
一开始用户增加上去了,服务器的Mysql 就%CPU 爆表, 130% 以上都有
第一步优化:
1. 高峰人数要找到同年级的排名比较耗时和没有太多实际意义,看的人其实可能不多,就临时先取消这个模块展示;
2. Mysql 表增加索引(效果非常显著)
但是好景不长,6日开始,就Mysql 又爆表了,想着,该加的索引都加上了,不知道因为什么导致(其实这个时候就算有遗漏也不好发现)
这个时候Mysql 的慢查询功能就可以摆上用场了。
netstat -na|grep -i "80"|wc -l
1562
top 查询 Mysql 占用最多CPU的资源,那肯定是因为同时在线的用户查询可能因为阻塞导致的大堵车,目前最重要的是要定位出来是什么的语句导致的。
慢查询有什么用?
它能记录下所有执行超过long_query_time时间的SQL语句, 帮你找到执行慢的SQL, 方便我们对这些SQL进行优化.
如何开启慢查询?
首先我们先查看MYSQL服务器的慢查询状态是否开启.执行如下命令:
我们可以看到当前log_slow_queries状态为OFF, 说明当前并没有开启慢查询.
开启慢查询非常简单, 操作如下:
Linux下找到mysql的配置文件my.ini, 在mysqld下方加入慢查询的配置语句(注意:一定要在[mysqld]下的下方加入)
log-slow-queries: 代表MYSQL慢查询的日志存储目录, 此目录文件一定要有写权限;Windows下需要写绝对路径,如:log-slow-queries="C:/Program Files/MySQL/MySQL Server 5.5/log/mysql-slow.log"
long_query_time: 最长执行时间. (如图, MSYQL将记录下所有执行时间超过2s的SQL语句, 此处为测试时间, 时间不应太小最好在5-10秒之内, 当然可以根据自己的标准而定);
配置好以后重新启动一个MYSQL服务
然后查看log发现了问题
SELECT * FROM `fd_members` WHERE `unionid` = 'oh6a0s65Oh8rTtFLoW9Pf0***' LIMIT 1;
都是因为这样类似的语句记录,说明这条查询非常久(表里边大概有30多万条记录),测一下,当时候服务器查询要13秒左右,坑爹的,那怪堵车那么严重。
然后再看数据库表结构,原来members 表的uniond 没有加入索引,赶快补充上了,然后再测试,就变成了 10ms 不到就出来了。这差别是 千倍数呀!!
开了后的效果,如下,立竿见影
晚上统计了一下,今天一共来的人数,在Nginx 的地方还有好多要优化的地方