商城首頁卡爆了!!!
來源:蘇三說技術
前言
最近我們的商城系統出現了一個線上問題,使用者訪問商城首頁的時候要差不多20秒,才返回資料,可以說卡爆了。
到底怎麼回事呢?
1.案發現場
上週四晚上,我們有一個正常的迭代版本按照預期的時候上線。
本次迭代,我所涉及的功能,很快上線,並且測試透過了。
但沒法下班,因為專案組其他同事,還有線上問題在緊急處理。
我過去了解了一下情況,使用者訪問商城首頁的時候響應太慢了,要20秒才返回,有使用者投訴過來了。
進一步瞭解之後發現,造成這個問題的根本原因是redis伺服器掛了。
為什麼會掛呢?
是因為一次性往redis中儲存的資料太多了,導致記憶體不足。
這個商城系統部署到了阿里雲上,當時購買了1G的記憶體空間。
但由於這次上線,有個新功能,需要在商城首頁上,按不同的地區,推薦不同的商品。商品還要按不同的分類做區分。
原本商品只有幾十萬其實不多,但是按地區和分類做區分之後,儲存的資料量乘以了幾百倍,一下子佔用了大量的記憶體。
redis掛了為什麼會導致首頁慢呢?
答:因為程式碼中有業務邏輯,如果從redis中沒有獲取到資料,或者訪問redis失敗了,會從資料庫中獲取。雖說當時是晚上,使用者併發量不大,但是直接訪問資料庫,響應時間一下子下降了很多。
2.如何快速解決問題?
目前的這套方案,先從redis中獲取資料,如果失敗了,再從資料庫中獲取。
現在的問題是:redis記憶體不足,臨時解決問題,只能加記憶體資源了。
因為加記憶體是最快的,直接加到了4G。如果要改程式碼,這個功能今天晚上可能沒法上線,之前購買的1G的資源確實有點小。
在阿里雲上redis加了記憶體之後,這個問題很快解決了,首頁訪問速度一下子提升。
但這不是問題的本質。
3.覆盤
第二天,我們開始覆盤問題。
發現之前的方案有點問題:
這次新增的推薦商品功能,儲存到redis的資料量太大了,把有些為null值的欄位,或者前端用不到的欄位也儲存到redis中了,資料結構設計不合理。 redis出現問題之後的兜底方案有點問題,如果redis掛了,就直接訪問了資料庫,導致了使用者訪問慢的問題。如果是白天使用者併發量上來,可能會直接導致資料庫掛掉。
那麼,如何最佳化呢?
4.如何最佳化?
資料結構不合理的問題,可以透過調整資料結構解決,非常容易。
但如果redis掛了該如何處理呢?
4.1 頁面靜態化
其實對於商城首頁,最好的方案是做頁面靜態化處理。
但由於目前商城的使用者併發量,還不算很大,而且如果改成頁面靜態化,前後端的改動都太大了。
因此,這個方案最先被我們否定了。
4.2 加本地快取
為了防止後面再次出現商城首頁訪問慢的問題,可以在應用服務增加本地快取。
這樣不管redis以後能否正常執行,都不影響商城首頁的功能。
但需要考慮一個事情:應用服務的記憶體是否夠用?
顯然如果將所有推薦的商品資料,都儲存到應用服務的本地記憶體中,同樣可能會導致應用服務的記憶體不足的問題。
因此,直接加本地記憶體是不行的。
4.3 改成MongoDB
使用MongoDB替代Redis儲存資料。
Redis:資料全部存在記憶體,定期寫入磁碟,當記憶體不夠時,可以選擇指定的 LRU 演算法刪除資料。
MongoDB:資料存在記憶體,由 linux系統 mmap 實現,當記憶體不夠時,只將熱點資料放入記憶體,其他資料存在磁碟。
顯然MongoDB更適合儲存大批次的結構化的文件資料。
由於我們之前在做其他功能時,使用過MongoDB,它的效能也是挺不錯的。
但如果直接改成從MongoDB中獲取資料,商城首頁的訪問速度可能會有所下降。
4.4 本地快取 + MongoDB
上面說到過的加本地快取,和使用MongoDB都有各自的優缺點。
為什麼不把兩種方案結合一下呢?
在本地快取中儲存熱點資料,每隔5分鐘更新一次。
使用者的請求過來,先從本地快取中獲取推薦商品資料,如果有則直接返回。
如果沒有,則從MongoDB獲取資料。
這樣可以解決效能的問題,也可以解決儲存大量的資料。
5.兜底方案
上面的說的本地快取 + MongoDB,基本可以解決redis掛了的問題。
但如果MongoDB掛了該怎麼辦呢?
這就需要有一套更好的兜底方案。
5.1 使用Apollo配置
如果MongoDB掛了,則直接返回Apollo配置中預設資料,預設是北京市東城區的推薦商品資料。
該配置由於在Apollo中,我們可以根據實際情況動態調整。
我們都知道Apollo可以配置成叢集模式,是高可用的,一般不容易掛掉。
但它有一個硬傷,就是如果資料並更了,需要人手動調整資料。
沒法保證資料的實時性。
5.2 再從資料庫訪問資料
如果從MongoDB中獲取資料失敗了,則直接從資料庫中獲取資料。
該方案從業務的角度來說,確實沒有問題。
但萬一真的出現這種情況,同樣會出現商城首頁訪問很慢的問題。
5.3 再從redis訪問資料
如果從MongoDB中獲取資料失敗了,則直接從redis中獲取資料。
Redis中只保留熱點商品資料。
這也是一種方案,不過要維護兩份資料:MongoDB一份,Redis一份。
可能會存在資料不一致的問題。
5.4 再加一個本地快取
在從資料庫獲取資料之後,再加一個本地快取,儲存預設的資料,即:北京市東城區的推薦商品資料。
這個本地快取,只有在第一次訪問資料庫時寫入,並且有效期是24小時。
相當於在MongoDB和資料庫之間,再加了一層預設的本地快取。
這樣就能解決資料庫訪問慢的問題。
6.最終方案
經過激烈討論之後,我們最終選擇的方案是:本地快取+MongoDB+本地預設快取+資料庫。有時候選擇的某一個技術方案,是根據當前的業務發展,或者公司現狀,資金,資源,人手,技術能力等多方面考慮的。
很多技術問題都沒有最完美的解決方案,只有最適合的方案。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024924/viewspace-3001512/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一手全新卡首頁
- 短視訊商城原始碼,首頁輪播圖佈局管理原始碼
- 完了!Windows弱爆了!它才是程式設計師的首選!Windows程式設計師
- Windows弱爆了!Linux才是程式設計師的首選!真的好用!WindowsLinux程式設計師
- 勁爆:首屆中國Rust語言大會終於來了!Rust
- 2019阿里雲開年Hi購季必搶!爆爆爆爆爆爆爆款清單來了!阿里
- 實現不同頁面不同頁首
- 如何設定word首頁封面不出現頁首和編碼
- 卡米黛爾系統卡米黛爾商城系統
- rm命令弱爆了!
- 模仿NetFlix首頁效果
- 港澳臺暢銷前六,網易寶船的首個“小爆款”出現了?
- ZBlog首頁與列表頁相關模板
- wkhtmltopdf 生成帶頁首頁尾的pdfHTML
- Java 在PDF中插入頁首、頁尾Java
- Excel2007怎麼插入頁首和頁尾?Excel2007插入頁首頁尾的方法步驟Excel
- 網易CCG卡牌井噴,哈利波特爆火後,漫威對決又來了
- 網頁佈局------小米商城官網網頁
- 完了!Windows弱爆了!它才是程式設計師的首選!程式設計師:真的好用!Windows程式設計師
- 404頁面自動跳轉到首頁
- 網頁效能 CaseStudy:以 PressOne 首頁為例網頁
- 5 月,Java 崗位爆了???Java
- MySQL 的 join 功能弱爆了?MySql
- Word文件中怎麼新增頁首或頁尾?
- 定製論文頁首頁尾設定需求
- 新金寶公司-19188193789首頁
- iOS首頁渲染優化 -- imageName:iOS優化
- HeyUI新版首頁設計之路UI
- win10系統下word文件如何新增頁首頁尾_win10 word文件頁首頁尾怎麼設定Win10
- 如何快速刪除Word中的頁首橫線?刪除頁首橫線技巧分享
- 使用mybatis分頁外掛展示首頁最新視訊MyBatis
- 暢購商城(七):Thymeleaf實現靜態頁
- 列印頁面時怎樣自定義列印頁首頁尾或者去掉眉頁尾?
- wps頁首怎麼取消與上一節相同 wps怎麼設定不同的頁首
- 小米中信銀行推聯名信用卡 開卡可得小米商城代金券
- 首測引發全球多地廣泛好評!2022全球女性向遊戲爆款可能就是它了遊戲
- 公司網站首頁突然亂碼網站
- Vue首頁效能優化之gzipVue優化