1. 程式人生 > >淺談後端高併發的幾種設計方法

淺談後端高併發的幾種設計方法

在高併發的應用場景中,前端需要更快的渲染速度,而後端不僅需要更快的介面速度,而且還需要保證資料的一致性。

前端設計中可能會有靜態頁面,cdn等的優化手段,在後端架構中,通常也需要引用高併發程式的解決方案。下面主要談談後端的處理方案。

分層

後臺主要有兩塊,一塊是資料庫,一塊的業務塊,當然業務層裡面還可能包含對別的服務呼叫。

資料庫層使用的優化手段

1.分庫分表。但是在做設計的時候最好考慮到在不停機的狀態下可以對庫表進行擴容。

2.sql的優化。查詢時指定列名,使用索引,用between代替in......

業務層優化

1.資料來源

這一層是主要講解的點,其實它可以細分為很多小類。你們姑且認為從前端的請求到請求結束都算業務層,當然這裡需要去除掉資料來源。

資料來源分三種:資料庫資料其他介面資料快取中資料

針對資料庫資料,上面已經給出了相應的解決方法。

針對呼叫其他介面資料,當然是依賴的介面響應越快越好,但是需要注意如果下游介面遲遲沒有響應結果,需要做超時或者重試機制。說白了就是要cut掉當次請求,不能讓這個請求造成整個伺服器崩潰(當然這裡有點誇張的成分)。

針對快取中資料,需要考慮到快取的新鮮度,但是一般來說都是不經常變動的資料適合做快取。還需要考慮到快取資料的大小在事先應該做一個評估,不能造成記憶體不足。解決辦法也很簡單,要麼減少快取,要麼加機器記憶體。有一點建議需要提一下,儘量對同一個資料快取一次,比如有一個使用者物件,一會用名字和性別做key,一會用名字和年齡做key,一會又。。。這樣一個數據被快取了多次,白白佔用記憶體大小,直接用使用者id快取資料就可,判斷邏輯不應該作為key,而應該方法在程式裡面去做判斷。快取還需要注意的點有快取穿透,快取雪崩,當然有時還會用熱點資料。

在自身程式處理的過程中,需要區分業務場景,有些場景是需要及時返回資料的,比如X寶的商品列表頁,X東的商品列表頁。有些場景是可以不及時相應,比如下單之後半小時之內有簡訊通知。

針對需要及時響應的場景,介面返回的資料應儘量簡單,比如可以做分頁返回,相同報文進行抽離等等。

針對不需要及時響應的場景,在高併發的場景下,可以藉助訊息佇列,業界有名的mq有kafka,rabbitmq,rocketmq,zonemq,activemq等等,它們處理1w/s插入應該是沒有任何問題的,具體還需要根據自身的業務做進一步的評估。

2.事務的一致性

但是有一個問題似乎忽略掉了,如何保證事務的一致性?

在分散式事務中,有一個有名的cap(一致性,可用性,分割槽容忍性

)理論,事實告訴我們很難三個特性都滿足,一般業界用的最多就是使用mq來保證事務的最終一直性(可以有延遲,但是最終正確結果使用者還是可以看到的);當然還有x寶的GTX解決方案,它底層是基於2pc來實現了,解決分散式事務也很強勁。

程式碼設計中如果可以不要鎖最好就不使用,如果要使用也優先考慮重入鎖,樂觀鎖。

3.控制請求

有可能訪問量就是很大,而你的服務最多隻能承受住1000萬的訪問量,其他請求你可以用佇列做延時等待處理(最好考慮到時效性),也可以拋棄請求。如果有使用者惡意刷流量,可以通過程式碼限制ip訪問量,也可以通過nginx限控。

4.服務宕機

服務有的時候並不是100%可靠的,這是需要做服務的熔斷處理。服務在一定的時間端內傳送的請求都不能響應,那麼應該從伺服器叢集中將這個服務設定到為未可完全使用狀態。通過定時機制向叢集傳送自身的健康狀況,如果過一段時間服務好了,那它可以從叢集中分一部分流量響應,響應正常的話,使它重新加入叢集變為可用狀態。如果過一段時間服務還是沒有好,叢集就將它徹底從服務中刪除,併發出告警郵件!

5.響應速度

在高併發的訪問中,介面的響應速度需要儘可能的快。從兩個方面來談談這個問題:

1.jvm層

儘量不要觸發full gc,這個過程耗時非常嚴重,同時young gc的時間也需要儘可能的短,超過1s就要找找耗時點。

2.程式碼層

使用快取服務(本地快取,redis...),使用非同步方式(執行緒池...)呼叫。

3.系統層

叢集....