項目背景:
一個通過微信網頁訪問在線答題的功能 ,目標用戶覆蓋江西全省大中小學生。
阿里云服務器性能:
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 又爆表了,想著,該加的索引都加上了,不知道因為什么導致(其實這個時候就算有遺漏也不好發現)
7天內的CPU使用率
這個時候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 不到就出來了。這差別是 千倍數呀!!
開了后的效果,如下,立竿見影
image.png
晚上統計了一下,今天一共來的人數,在Nginx 的地方還有好多要優化的地方
人數