又到週六了,終於又能夠休息兩天,不過學習還不能中止,今天分享一下星球球友 @樓下小黑哥關於秒殺的分享。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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。