首頁 > 科技

一文詳解高併發以及提升系統併發能力

2021-06-28 12:10:50

在面試中面試官90%以上的機率都會問到高併發相關項目經驗。結合我面試候選人的一些經驗以及對高併發的理解,給大家一些完整的建議。首先說一下,在我作為面試官問候選人「對高併發的理解」時候,主要是想考察面試者是否有真實項目經歷

如果答的不好,有以下幾種情況:

(1)對資料化指標沒有概念:完全不清楚什麼樣的指標來衡量高併發系統,分不清併發量和QPS,不知道自己系統的總使用者量、活躍使用者量等等。

(2)涉及過一些高併發方案,但不知其所以然。也就是根本說不出當時方案要關注的技術點是什麼。

(3)把高併發當成效能優化,大談特談併發程式設計,多級快取等,不說高可用涉及和服務治理。這種我認為連概念都不清楚。

(4)有方案,沒意識。瞭解垂直分層、水平分區、快取等大思路。卻沒有分析資料結構、演算法是否合理高效的意識。

基於以上幾點,本來想從概念和設計目的給大家介紹,但是思考覺得過於抽象。決定用實際案例給大家詳細闡述業務痛點和系統設計的方案,這樣不僅梳理了解決問題的思路,也構建了面試的回答思路。

實際案例

網際網路分散式系統架構設計必須要考慮高併發,高併發也是大家經常會遇到的技術難題。如何控制庫存避免超賣?怎麼實現執行緒間的資料處理同步?以上圖紅包雨為例詳細介紹。

業務要求以及痛點分析

紅包雨項目是抽獎類系統的一種,要求在某一段時間內隨機發獎品,使用者參與活動。這個業務主要是管理後臺、使用者前臺和開發平臺構建。

其中後臺需要涉及到:使用者管理、獎品管理、活動管理、中間統計等功能;

使用者前臺屬於:註冊登入、參與抽獎,個人中心檢視。

開發平臺涉及到的內容:微服務架構體系、註冊與服務發現Nacos、部署平臺、介面Swagger等。

項目的重點在於高併發情況下及時響應,以及大批使用者點選用於,如何保障抽獎的獎品數量,不能出現設定了8個獎品,10箇中獎的情況。以及紅包出現在什麼時候,獎品抽中機率等等。

庫存控制以及核心流程

令牌桶演算法可以把請求平均分散在時間段內,是使用較為廣泛的限流演算法。我們可以把令牌桶演算法應用到紅包雨業務案例中。這時候,令牌相當於獎品票據;令牌桶相當於獎品庫存;正常業務相當於中獎;限流相當於未中獎。同時要注意,有多少個獎品,就生成多少個令牌(時間戳),未中獎返還令牌。假設活動時間間隔太短,獎品太多,極有可能產生的時間戳發生重複。為了解決這個問題,我們需要額外附加一個隨機因子,將( 時間戳*1000+3位隨機數)作為令牌,抽獎時將抽中的令牌除以1000來還原真實的時間戳。

最後,將拿出令牌、判斷時間、放回令牌的操作下沉到Redis伺服器端,利用Lua指令碼避免出現插隊導致的令牌順序被打亂。通過這些操作和解決方案,相信可以避免打亂獎品令牌造成扎堆出現的問題。

發散思維

使用Lua指令碼,將抽獎的邏輯從Java端移入Redis伺服器端,作為一個整體函數暴露給Java呼叫,一方面實現中獎邏輯的原子性,另一方面減少了Java伺服器與Redis伺服器之間的通訊次數,效能會得到提升。要實現活動隨時暫停,可以新增一個介面,該介面修改Redis快取中的活動狀態。抽獎介面邏輯中增加暫停狀態判斷。如果是暫停,返回給前臺以提示。要實現多種投放策路,可以修改令牌生成部分程式碼。按遞增、遞減、正態分佈等多種函數生成時間戳。

知識點總結

高併發(High Concurrency)是網際網路分散式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。

提高系統併發能力的方式,方法論上主要有兩種:垂直擴展(Scale Up)與水平擴展(Scale Out)。前者垂直擴展可以通過提升單機硬體效能,或者提升單機架構效能,來提高併發性,但單機效能總是有極限的,網際網路分散式架構設計高併發終極解決方案還是後者:水平擴展。

網際網路分層架構中,各層次水平擴展的實踐又有所不同:

(1)反向代理層可以通過「DNS輪詢」的方式來進行水平擴展;

(2)站點層可以通過nginx來進行水平擴展;

(3)服務層可以通過服務連線池來進行水平擴展;

(4)資料庫可以按照資料範圍,或者資料雜湊的方式來進行水平擴展;

各層實施水平擴展後,能夠通過增加伺服器數量的方式來提升系統的效能,做到理論上的效能無限。


IT145.com E-mail:sddin#qq.com