秒殺真那麼難?手把手帶你優化秒殺流程

天天早上七點三十,準時推送乾貨

又到週六了,終於又能夠休息兩天,不過學習還不能中止,今天分享一下星球球友 @樓下小黑哥關於秒殺的分享。web

晚上聽了架構師之路沈劍老師的一場關於秒殺業務的直播分享,總結了一下,分享一下給你們。面試

秒殺業務最大的業務特色,短期內,高併發,大量讀請求,大量的寫請求。若是不經任何優化,直接將所有讀寫請求打到數據庫層,數據庫層因爲鎖衝突,特別是熱點數據行鎖衝突,很容易形成死鎖,下降數據庫執行效率。並且流量很大的狀況,很容易將會把數據庫壓死。數據庫層若掛了,若是再次啓動,極可能又會被大流量再次壓垮。數據庫

從系統的角度來看,在秒殺業務的狀況下,咱們要保護數據層的安全。瀏覽器

爲了保證數據庫的安全,咱們就要下降最後到達數據庫層讀寫流量,使其一直處於安全的狀況下運行。緩存

從讀寫方向,優化思路:安全

  • 降讀
  • 降寫

下降數據層讀請求,主要辦法就是加緩存,數據優先讀取緩存,緩存不存在再從數據庫層讀取。緩存解決辦法比較多,下面主要介紹降寫的處理辦法。服務器

下降數據層寫請求,咱們就必須在上游應用層過濾寫清求。微信

技術優化手段

假設咱們的系統架構以下:網絡

網站/APP---->站點接入應用------>後臺服務---->數據庫層架構

咱們能夠在這三層作優化,攔截寫請求,下降數據層寫壓力。

在網站/APP 層,咱們可使用 JS 等手段,防止用戶重複點擊。

不過這種手段只能預防普通用戶,高級用戶能夠經過抓包獲取請求接口,經過程序發起,繞開 JS。

因此咱們須要在站點接入層經過計數的方式,防止同一用戶頻繁發送請求。好比咱們能夠限制同一用戶每 5 秒,只有一次請求才有效,其他請求返回請求速率過快。

站點層只能限制單一用戶,能夠經過多用戶手段繞開這一限制。

等到寫請求到達服務層,服務層能夠發送到 MQ 隊列或者內存隊列,而後根據庫存數量,或者數據庫抗壓能力處理。

好比說某件商品庫存只有 2000 個,這時服務層現收到 2 w 個寫請求,所有發送到隊列中。假設數據庫層只能最大隻能處理 1000 個寫請求,那咱們消費程序就拉取 1000 條消息,真正進行數據寫請求。

寫入成功以後,再次消費消息,直到庫存爲 0 。這時剩下的消息,都無需再執行數據庫的寫請求。

產品手段

除了上述的技術手段以外,咱們還能夠在產品設計方面減小寫請求。

咱們能夠在頁面使下單按鈕置灰,防止重複點擊。

咱們還能夠頁面是不顯示庫存具體數量,只顯示庫存的是否還有,下降緩存的淘汰率。

咱們還能夠將下單與支付流程分離,下單成功後,才能去支付。這時支付系統的壓力就很小不少。

相關問題

站點層服務壓力很大的處理方案

在咱們上面的方案中,站點接入層須要計數過濾,壓力可能會很大。因爲站點接入層通常都是無狀態應用,能夠水平擴展。因此咱們能夠適當增長機器,增長處理能力。

另外,咱們還能夠設置必定閾值,等請求到達閾值以後,服務降級,拋棄後續請求。

計數問題

計數咱們能夠存儲在 Redis 中,若是 Redis 性能不夠,咱們能夠水平擴展,使用相似 Redis Cluster 方案。

Redis 吞吐量很大,若是懼怕網絡帶寬成爲瓶頸,咱們能夠考慮不使用 Redis ,直接在內存中計數,不過這種方案就須要考慮數據一致性。

若是使用內存計數,同一用戶的請求就必須落在同一臺機器上。這裏的處理的方案咱們能夠在 Nginx 層使用 用戶 ID 切分,而後在分發到的站點接入層。

另外使用內存計數,咱們下降數據的一致性與準確性,容許因業務重啓,致使內存的丟失的狀況。

隊列異步處理,瀏覽器/APP處理方式

1.在請求發送到隊列中時,咱們能夠提早預分配一個訂單號,消息發送成功,將訂單號返回給頁面

2.瀏覽器/APP 拿到訂單號返回以後,跳轉到中間也,而後定時輪詢。頁面咱們能夠提示用戶,訂單正在排隊中,若刷新將會再次進入排隊,防止用戶再次刷新下單。



< END >

若是你們喜歡咱們的文章,歡迎你們轉發,點擊在看讓更多的人看到。也歡迎你們熱愛技術和學習的朋友加入的咱們的知識星球當中,咱們共同成長,進步。




往期 精彩回顧




面試官:生產服務器變慢了,你能談談診斷思路嗎
面試官提問:如何去掉list集合中重複的元素?
引入兩個依賴以後,阿粉一週內就完成了網站的登陸改造|實戰開發


本文分享自微信公衆號 - Java極客技術(Javageektech)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索