1. 程式人生 > >一條慢SQL導致購物車服務無法使用

一條慢SQL導致購物車服務無法使用

概述


之前處理過一個購物車故障,覺得還挺經典的,在這裡跟大家分享一下。這個故障直接導致前端新增購物車、獲取使用者購物車列表等操作都失敗了。購物車是入口,一旦出現問題,影響極其嚴重。


臨時處理


購物車服務所有介面,是有列印響應時間的,發現比平時慢了很多。由於情況已是十萬火急了,我只能先重啟購物車,緩衝一下,然後利用這段緩衝時間,趕緊定位問題。


問題定位


之前對購物車應用基於Spring Cloud微服務化了,已經穩定運行了幾個月了,且當時上線前也經過壓測,介面效能是沒問題的。怎麼突然之間就有問題了呢?根據以往的經驗,大部分故障都是SQL

語句引起的,因此首先匯出資料庫的所有慢SQL(騰訊雲有匯出慢SQL的工具)語句,發現大部分慢查詢都是來自庫存查詢的SQL語句,有些甚至是10秒鐘才執行完。

後來仔細一看,庫存慢查詢語句,要查詢庫存的商品比平時多很多。商品個數少的話,這條語句還是非常快的,一旦多了就開始慢了。


解決方案


由於庫存計算體系的歷史原因,這條SQL是很難優化的。情況又是十萬火急的,大老闆一直在問咋回事。因此臨時改程式碼,將商品庫存放到Redis快取起來。購物車服務的話,是允許庫存資料不實時的,因為後面的結算和支付會實時計算庫存,庫存不足的時候,會提示使用者的。

注意:

  • 由於購物車是入口,流量很大,而從購物車到結算頁再到支付,由於有一個操作步驟,因此結算頁和支付頁的流量是沒有購物車那麼大的;
  • 部分使用者購物車上的商品資料是非常多的,但是未必都會買,使用者也可以勾選要買的商品,然後下單;
  • 部分使用者沒有清理購物車失效商品的習慣,導致購物車上的商品非常多。

終極解決方案


將庫存服務獨立出去,將商品庫存資料放置到快取,並引入實時重新整理快取中庫存資料的機制,讓快取中的資料儘量保證新鮮。這樣的話,查詢庫存的時候,大部分都可以從快取中獲取,不會穿透到資料庫上。


補充


我們對介面進行壓測的時候,部分場景下,要考慮入參的個數,不能簡單的用幾個資料壓測,覺得效能OK就不管了。