分散式下的問題
1.session共享,使用redis儲存session資訊,主從複製慢可以在程式碼中手動寫入
2.分散式事務
兩階段提交協議
使用訊息中介軟體
3.負載均衡
4.分散式鎖
一致性hash演算法
用處:分散式快取
演算法描述:
先構造一個長度為232的整數環(這個環被稱為一致性Hash環),根據節點名稱的Hash值(其分佈為[0, 232-1])將伺服器節點放置在這個Hash環上,然後根據資料的Key值計算得到其Hash值(其分佈也為[0, 232-1]),接著在Hash環上順時針查詢距離這個Key值的Hash值最近的伺服器節點,完成Key到伺服器的對映查詢。
避免hash傾斜性方法:引入虛擬節點
將一個物理節點拆分為多個虛擬節點,並且同一個物理節點的虛擬節點儘量均勻分佈在Hash環上
訊息佇列的應用場景
1.非同步處理(如傳送簡訊)
2.應用解偶
3.流量銷峰(秒殺活動限流)
4.日誌處理
5.訊息通訊(點對點通訊或聊天室)
高併發下的效能優化
1.調整專案結構,增加伺服器資源,叢集或分散式,負載均衡
2.資料庫優化
3.程式碼優化(使用多執行緒+演算法優化)
4.合理使用快取
5.html靜態化,圖片存於伺服器
介面如何處理重複請求
前端控制:當使用者點選按鈕後將按鈕disable掉,後端不返回資料時不可點選
後端控制:uriPath+userId+MD5(JsonString(所有引數))作為key,用redis分散式鎖,用spring aop來實現,對resource method 做aop攔截
主要是利用唯一Token值與提交引數相匹配驗證。
介面限流演算法
1.計數器法(最簡單最容易實現):假設要求某個介面一分鐘之內不能超過100個請求:設定一個count,每次請求count++,在count>100時判斷時間有沒有超過一分鐘,超過說明請求過多;如果沒超過說明還在範圍之內,那麼重置count
缺陷:在臨界值(如59秒時傳送100個請求,在00時又傳送100個請求,會認為是兩個時間段,但其實2秒之間就會有200個請求,這樣很容易擊垮應用)
2.滑動視窗:將時間細分為很多格,每過n秒向右移動n格,可以避免上述問題
3.漏桶演算法:設定一個容量固定的桶,流入的速率未知,流出去的速度恆定,多餘的水會溢位
優點:使用了漏桶演算法後我們可以保證介面會以一個常速速率來處理請求。
缺點:不能應對突發流量
4.令牌桶演算法(使用最多):設定一個容量固定的桶,裡面存放令牌(token),以一個恆定的速率往桶裡放令牌,介面請求過來時,會從桶裡取出一個令牌,有令牌才可以通過,沒有令牌時無法通過,這就保證了介面的請求速率。
解決臨界值問題:就算在一瞬間令牌全部被取完了,但是往桶裡放令牌的速率是很慢的,這就保證了後面的請求不會在一瞬間通過。
分散式下的限流可以利用redis來實現
分散式快取:
快取分級:本地快取-->redis快取-->tomcat堆快取-->mybatis或DB快取
分散式下要特別考慮的問題:不能多個程式同時寫值,必須保證原子性,不能出現髒資料
redis快取的負載策略:建議首先採用一致性hash演算法(可以保證相同的請求會打在同一臺伺服器上,並且不隨擴容而降低),當到達一定的閾值後切換為輪詢演算法,這樣既能保證快取命中又能保證服務的高可用