其實拋開秒殺這個場景來說正常的乙個下單流程可以簡單分為以下幾步:
3.1 超賣現象(使用樂觀鎖更新)
3.2 提高吞吐量
為了進一步提高秒殺時的吞吐量以及響應效率,這裡的 web 和 service 都進行了橫向擴充套件。
當併發量達到幾百萬時(分布式限流)
我們將併發控制在乙個可控的範圍之內,然後快速失敗這樣就能最大程度的保護系統。
3.3 sql查詢太多(redis快取)
這種資料我們完全可以放在記憶體中,效率比在資料庫要高很多。
由於我們的應用是分布式的,所以堆內快取顯然不合適,redis 就非常適合。
這次主要改造的是 service 層:
3.4請求同步轉非同步(kafka)
這裡我們將寫訂單以及更新庫存的操作進行非同步化,利用 kafka 來進行解耦和佇列的作用。
每當乙個請求通過了限流到達了 service 層通過了庫存校驗之後就將訂單資訊發給 kafka ,這樣乙個請求就可以直接返回了。
消費程式再對資料進行入庫落地。
因為非同步了,所以最終需要採取**或者是其他提醒的方式提醒使用者購買完成。
其實經過上面的一頓優化總結起來無非就是以下幾點:
簡單理解下悲觀鎖:當乙個事務鎖定了一些資料之後,只有當當前鎖提交了事務,釋放了鎖,其他事務才能獲得鎖並執行操作。
這裡使用select for update的方式利用資料庫開啟了悲觀鎖,鎖定了id=1的這條資料(注意:這裡除非是使用了索引會啟用行級鎖,不然是會使用表鎖,將整張表都鎖住。)。之後使用commit提交事務並釋放鎖,這樣下乙個執行緒過來拿到的就是正確的資料。
悲觀鎖一般是用於併發不是很高,並且不允許髒讀等情況。但是對資料庫資源消耗較大。
那麼有沒有效能好,支援的併發也更多的方式呢?
那就是樂觀鎖。
樂觀鎖是首先假設資料衝突很少,只有在資料提交修改的時候才進行校驗,如果衝突了則不會進行更新。
通常的實現方式增加乙個version欄位,為每一條資料加上版本。每次更新的時候version+1,並且更新時候帶上版本號
借下圖
image.png
樂優.png
註冊中心(eurake) : @enableeurekaserver開啟註冊中心,實現對各種微服務的集中管理
閘道器徽服務(zuul) : @enablediscoveryclient將服 務註冊到到註冊中心,@enablezuulproxy開啟 閘道器服務,對微服務路口做統一管理, 實現路由,降級(容錯回退),限流的功能。如果多台伺服器,可以通過路徑和服務的繫結path: /user-service/* ; serviceld: user-service2,實現負載均衡(預設是ribbon輪詢,還有隨機)
使用者中心微服務(user-service) :@enablediscoveryclient將 使用者中心微服務註冊到到註冊中心,實現註冊和登入功能
授權中心微服務(auth-service) : @enablediscoveryclient將使用者中心微服務註冊到到註冊中心實現對登入的鑑權。
商品微服務(item-service) : @enablediscoveryclient將商品微服務註冊到到註冊中心,做商品的新增和查詢。
閘道器對部分不需要登入認證的介面放行(要優化)1.註冊使用者,閘道器對註冊放行
登入介面到閘道器,被路由到授權中心,授權中心微服務呼叫使用者中心的登入介面進行校驗,校驗成功,利用jwt生成token,然後利用rsa非對稱加密token,生成公鑰和私鑰儲存,然後將token返回到客戶端
秒殺業務
在商品微服務中設定秒殺引數,根據引數的商品id查詢商品,構建商品秒殺表,新增,然後更新redis快取
boundhashoperations hashoperations = this.stringredistemplate.boundhashops(key prefix);
1/判斷是否存在此k值
if (hashoperations.haskey(key prefi){
hashoperations.delete(key_ prefix);
seckiloods.foreach(goods > hashoperatiosput(goos.getkud(.totring(), goods.getstock).totrin));))
使用秒殺功能需要登入驗證,建立登入攔截(logininterceptor extends handlerinterceptoradapter)對token進行驗證,認證通過將使用者資訊存放到執行緒域中,並且走乙個限流攔截accessinterceptor extends handlerinterceptoradapter)實現限流功能
構建秒殺路徑(限流),加密,儲存到redis快取,隱藏秒殺路徑,防止刷單。
4.1. 驗證秒殺路徑
4.2. 讀取庫存, 減1後更新快取
4.3. 庫存不足直接返回「排隊中」
4.4. 庫存充足, 將商品資訊封裝入隊mq,然後直接返回「排隊中」
然後訂單微服務監聽佇列,消費佇列,
5.1判斷庫存不足,將該商品設定成不可秒殺狀態,
5.2檢視是否秒殺到,秒殺到直接返回,
5.3沒有秒殺到,建立訂單
秒殺系統設計
秒殺場景一般會在電商 舉行一些活動或者節假日在12306 上搶票時遇到。對於電商 中一些稀缺或者 商品,電商 一般會在約定時間點對其進行限量銷售,因為這些商品的特殊性,會吸引大量使用者前來搶購,並且會在約定的時間點同時在秒殺頁面進行搶購。限流 鑑於只有少部分使用者能夠秒殺成功,所以要限制大部分流量,...
秒殺系統設計
一 穩 1 前端 1 前端靜態資源快取 cdn 按鈕置灰 ip限流 一段時間內現在使用者ip 2 同一userid限制訪問頻率,超過頻率返回同乙個頁面,進行限流。利用驗證碼防止惡意攻擊。後端 1 請求丟到mq中按照訊息佇列進行處理,進行削峰 2 因為秒殺是讀多寫少,把庫存資料預先載入到redis中,...
秒殺系統設計
1 什麼是秒殺系統 秒殺系統 就是網路商家為 商品,以低 商品賣出做的限時限量搶購活動 2 秒殺系統可以解決什麼問題,用在哪些場景 解決問題 解決網路商家快速 商品,以低 商品賣出做的限時限量搶購活動 應用場景 商品搶購 3 秒殺系統會出現什麼問題,解決方案 出現的問題 1 併發量大 2 防止超賣 ...