? 并發(fā)隊列的選擇
? Java的并發(fā)包提供了三種常見的并發(fā)隊列實現(xiàn):arrayblockingqueue、concurrentlinkedqueue和linkedblockingqueue。
? ArrayBlockingQueue是一個具有固定初始容量的阻塞隊列,它可以作為數(shù)據(jù)庫模塊(如10項)的成功投標隊列,因此我們建立了一個10大小的數(shù)組隊列。
? Concurrentlinkedqueue是一個由CAS原語實現(xiàn)的無鎖異步隊列。進入隊列的速度很快,鎖定隊列后性能稍慢。
? LinkedBlockingQueue也是一個阻塞隊列,無論是進出隊列都被鎖定,當團隊為空時,線程將暫時阻塞。
? 在請求預(yù)處理階段,由于系統(tǒng)對進入隊列的需求遠遠大于離開隊列的需求,因此不會出現(xiàn)空隊列,因此可以選擇并發(fā)鏈接隊列作為請求隊列的實現(xiàn)
? 1.請求接口的合理設(shè)計
? seckill或snap-up頁面通常分為兩部分,一部分是靜態(tài)HTML和其他內(nèi)容,另一部分是參與seckill的web后臺請求接口。
一般情況下,靜態(tài)HTML等內(nèi)容都是通過CDN部署的,一般壓力并不大,核心瓶頸實際上是在后臺請求接口上。這個后端接口必須能夠支持高并發(fā)請求。同時,盡快返回用戶的請求結(jié)果非常重要。為了盡可能快地實現(xiàn),接口的后端存儲將與存儲器級操作更好。不適合直接面對MySQL等存儲。如果有如此復(fù)雜的業(yè)務(wù)需求,建議使用異步編寫。

? 當然,也有一些秒殺和閃購使用了“滯后反饋”,即秒殺目前還不知道結(jié)果,從頁面上可以看出用戶一段時間后秒殺是否成功。但這種行為屬于“偷懶”行為,用戶體驗不好,很容易被認為是“暗箱操作”。
? 高并發(fā)下的數(shù)據(jù)安全
? 我們知道,當多線程寫入同一文件時,有一個"螺紋安全"問題(多個線程同時運行相同的代碼,如果每個運行的結(jié)果與單個線程的結(jié)果相同),結(jié)果是線程安全(預(yù)期)。如果是MySQL數(shù)據(jù)庫,可以使用自己的鎖定機制來解決這個問題。但是,在大規(guī)模并發(fā)場景中,不建議使用MySQL。在殺人搶奪的場面中,還有另一個問題,那就是“超調(diào)”,如果在這方面不小心,就會造成太多的送人。我們也聽說一些電子商務(wù)公司從事閃購活動。買家成功拍照后,商家不承認訂單有效,拒絕送貨。這里的問題可能不一定是企業(yè)是奸詐的,但在系統(tǒng)的技術(shù)水平上存在超限風險。
? 1. 超發(fā)的原因
?? 假設(shè)在搶購的情況下,我們總共只有100種產(chǎn)品。在最后一刻,我們已經(jīng)消費了99種產(chǎn)品,只剩下最后一種。此時,系統(tǒng)發(fā)送多個并發(fā)請求,這些請求讀取的貨物的剩余量為99,然后全部通過該余量判斷,最終導(dǎo)致溢出。(與文章前面提到的場景相同)

? 在上面的圖中,并發(fā)用戶B也被“搶占”,讓另一個人訪問該產(chǎn)品。在高并發(fā)的情況下,這種場景很容易出現(xiàn)。
? 2. 悲觀鎖思路
? 解決線程安全問題的思路很多,可以從悲觀鎖的角度進行討論。
? 悲觀鎖,即在修改數(shù)據(jù)時,使用鎖狀態(tài)排除外部請求的修改。如果您遇到鎖定狀態(tài),您必須等待。

? 盡管上述解決方案確實解決了線程安全問題,但不要忘記我們的場景是“高并發(fā)性”。換句話說,會有很多這樣的修改請求,每個請求都必須等待一個"鎖",一些線程可能永遠不會有機會抓取"鎖",這樣的請求就會在那里死去。同時,會有很多這樣的請求,這會在瞬間增加系統(tǒng)的平均響應(yīng)時間。因此,可用連接數(shù)將耗盡,系統(tǒng)將陷入異常。
? 3. FIFO隊列思路
? 好吧,讓我們修改一下上面的方案,我們直接在隊列中使用FIFO(先進先出),這樣我們就不會引起一些請求永遠得不到鎖??催@里,把多線程變成一個線程不是有點強迫嗎。

? 然后,我們現(xiàn)在解決了鎖定問題,并且在"先進先出"隊列中處理了所有請求。所以新問題來了。在高并發(fā)場景中,由于請求較多,隊列內(nèi)存很可能在一瞬間突發(fā),然后系統(tǒng)進入異常狀態(tài)。或者大內(nèi)存隊列的設(shè)計也是一種解決方案,但是系統(tǒng)請求在一個隊列內(nèi)的速度不能與瘋狂涌流隊列的數(shù)量相比較。也就是說,隊列中的請求將越來越多地累積起來。最后,web系統(tǒng)的平均響應(yīng)時間會急劇下降,系統(tǒng)仍然會陷入異常狀態(tài)。
? 4. 樂觀鎖思路
? 在這一點上,我們可以討論樂觀鎖的想法。樂觀鎖是一種比悲觀鎖更為寬松的鎖機制,大多數(shù)悲觀鎖都是用版本更新的。該實現(xiàn)是所有對該數(shù)據(jù)的請求都有資格被修改,但是只有在版本號匹配時才會獲得數(shù)據(jù)的版本號,而其他的返回將失敗。這樣就不需要考慮隊列問題,但會增加CPU的計算成本。然而,從全面的角度來看,這是一個很好的解決辦法。

? 有許多軟件和服務(wù)支持樂觀鎖功能。例如,redis的手表就是其中之一。通過此次實施,我們保證了數(shù)據(jù)的安全