Java Web高併發搶單如何實現?

時間 2021-05-06 19:23:28

1樓:於Mr

簡單的,分布式服務用redis做個簡單的分布式鎖,因為redis是單執行緒多路復用,判斷incr返回就行,比如你有十個庫存,超過的全部返回失敗。其餘細節退貨或者下單失敗恢復庫存什麼的自己考慮一下。

2樓:張鵬飛

@圓胖腫 首先第一步,你得讓海量請求進來,第二步才是對進來的請求排隊處理。第二步只是時間問題,要麼像kafka那樣,要麼像redis那樣。第一步單機一定會遇到瓶頸,無論集群還是分布式,跨機器的處理都會多出io時間,vertx是怎麼讓多伺服器同時處理還省去io時間的?

這不科學吧?就算vertx單台伺服器可以處理很高很高的併發,也不可避免要用集群,因為要保障的事高可用,而不只是高併發,跨伺服器資料處理不可避免

3樓:

人家寫得很誠懇了,就不要再扔些空洞的話,順便鄙視鄙視題主,這個東西網上到處都是了,說到處都是的人,怎麼不順手搜乙個給他?

你的spring MVC是處理請求的,擷取到request以後,先解析,然後生成message。

接下來你需要乙個q,你有兩個選擇,spring integration去連普通的queue,比如開源的activeMQ,或者用spring amqp,像這個官網例子Spring AMQP

從q裡面取,當然是反向的,你選好了怎麼放,就對應的怎麼取。

這是簡單層面的,商用化的話,你還要考慮一致性,錯誤處理等,我感覺你是在練習,這些先別增加複雜度了。

這個message加入佇列,著乙個架構動作,和資料持久層並沒有關係。資料持久層應該是在兩部做動作,1,是加入q處理之前,你可能想永久化一下,2,是處理成message了,後台進行業務處理,那麼業務動作結果肯定要存在持久層裡面。

所以過程就是

4樓:

這種問題差不多已經爛大街了,各家電商實踐這麼多年,公開的資料都有很成熟的實踐思路甚至原始碼,看現有回答都還有各種各樣的問題,感覺各位真的很不走心的回答問題呢。

秒殺這個功能,往簡單的說就是乙個資源爭奪的典型例子。一些書裡經常會用多終端共享印表機來說明這種獨佔資源共享的場景。解決資源搶占衝突的手段往往就兩個,減少衝突方或增加資源。

秒殺需要占用的最重要資源是庫存計數,其次是執行時間。抓住這個關鍵點就好辦了,用什麼框架什麼技術,無非也就是保證這個計數不被髒讀髒寫,同時保障其他流程快速穩定地執行至結束。

那麼最簡單的思路,就是將請求排隊,再慢慢消化這些。也就是說,雖然很多訂單請求過來,但是真正處理訂單的處理程式就乙個,所有請求被佇列hold住後由單一程式處理,這樣直接避免了髒讀髒寫問題。這種方案用得最多的就是下邊很多答主提到的訊息中介軟體。

但這樣的方案是以降低吞吐量為代價的,畢竟僅安排一道程式處理佇列,佇列平均等待時間會非常長。

這種設計通常使用者會感覺秒殺後系統相當長時間失去相應。

高階的做法就是想辦法快速消耗佇列,比如不再使用單執行緒處理佇列,轉為僅使用佇列進行任務排程,並由排程程式控制庫存計數,訂單後續操作分派到其他執行緒甚至其他服務完成。這樣,庫存計數仍然由單執行緒順序操作,可以避免髒讀髒寫問題,同時排程執行緒可以迅速消耗佇列,佇列平均等待時間可以進一步縮短。

這樣的秒殺模型就變成了乙個,預先占有資源後併發處理後續流程的模型。如果搶占不到資源,排程器自然會將請求交由錯誤處理程式處理。

佇列平均等待時間減少帶來最直觀的感受,就是使用者覺得秒殺結果出來更快。

以上兩種方案,是以保護共享資源為出發點做文章,為了保護共享資源,不可避免的選擇降低資源訪問頻率來降低衝突可能性,從而影響程式速度和使用者體驗。

另一種思路是增加資源,從而進一步降低資源爭奪的可能。

其中一種較為廣泛的技術是多級快取機制,其根本原理是將單一的庫存計數以更細粒度拆分。這樣可搶奪資源變多,資源爭奪的概率就會降低。同時,這種設計還可以進一步橫向擴充套件,充分利用集群優勢。

更複雜的還有以單元架構為基礎,結合以上多種手段,從每年天貓雙十一後公開的文件看,幾乎能扛住所有秒殺流量了。

想清楚了這些手段,用的什麼框架,什麼儲存方案,幾乎都能建立起一套輕鬆抗百萬併發的系統,並不是其他回答所說的,框架不優秀導致,更不是簡單一句優化就可以做到的。

建議題主仔細分析自己的業務需要多高的複雜度,需要多複雜的實現,秉承夠用就好的選擇,選擇最佳方案。

5樓:ccloomi

使用訊息佇列解決這種問題是最好的了,將所有搶單請求推到乙個佇列中,系統只需要從佇列中乙個個取出處理即可。訊息佇列可以使用rabbitmq。

6樓:Edison Tian

比方說,你這個商品有10個庫存,然後10點05分05秒開搶。那開搶的時候,先把所有的請求給落地(可以落到redis裡面也可以落到資料庫裡面),然後按照請求時間從小到大排個序,那前10個就是真正秒殺成功的那10個,其餘的都算為秒殺失敗。

那具體是用redis還是mysql你可以再具體想一下,反正大致思路是這樣!

7樓:圓胖腫

瀉藥這就是乙個簡單的併發衝突的處理問題

用vert.x可以瞬間解決這個問題

誰讓你用spring?which壓根不解決併發衝突,spring設計其實很糟糕的

你這幾個裡面,比較合理的是通過redis來解決,但是也多了一層io效率會比較差

如何獲得高併發的經驗?

飛援科技 章躍平 首先,需要機會參與有高併發產品機會,因為實戰經驗是前提 其次,需要對網路,系統架構,開發語言,資料庫調優有足夠的知識 再次,需要和測試同事保持密切合作,在系統上線之前,把高併發問題扼殺在搖籃 最後系統上線後,做好監控,運維工作,隨時把握系統流量壓力。最後還需要再安全,防doss攻擊...

高併發下怎麼做餘額扣減?

瀟湘夜雨 餘額的扣減的方式通常有以下幾類 1 基於第三方元件的分布式鎖實現 2 for update的行悲觀鎖 3 基於cas的樂觀鎖 這幾類以及效能優化前面都有說明,我補充一下第三個基於cas導致的ABA問題的解決思路 ABA問題是由CAS衍生來的,在併發極端情況下會產生,那麼什麼是ABA問題?標...

1秒1000併發 高併發需要什麼樣的伺服器?

網易數帆 題主的兩個問題可以理解成高併發下對MongoDB的技術優化需求,可以從兩個層面出發考慮 首先我們知道幾個概念 MongoDB是NoSQL面向文件型儲存資料庫,屬於重記憶體的型別,特別是在MongoDB 3.2預設的 WiredTiger引擎下,缺省會占用大量的記憶體來保證自身效能。因此Mo...