淺談高併發和設計的一些原則(JAVA)

ohcomeyes發表於2018-10-29

前言

在設計一個系統的時候,因為場景時間而異資源配備等不是一下子就能設計得非常完美,在有限的資源下解決最核心的問題,預測並發現以後可能出現的問題,並逐步解決,所以說系統設計是一個不斷迭代的過程,不要過度設計,從迭代中演變和完善。

關於併發? 併發包括並行從概念上來講都是為了提高效率,在最短的時間內怎麼來完成最多的事情。 包括現在的雙十一、雙十二等等,在一秒鐘完成了多少的訂單,這些都會涉及到併發。 併發和並行 有大神關於兩者的闡述:“併發關乎結構,並行關乎執行”

  • 併發:在不同時間內處理多個任務,單個CPU輪流使用。比方說在你吃飯的時候去上了個廁所又回來吃飯。
  • 平行:同時處理多個任務,多個CPU執行。比方說你邊吃飯邊上廁所。

併發型別

  • 計算密集型:需要非常多的CPU計算資源,對於密集型完全取決CPU核數,避免過多的執行緒上下文切換來充分發揮優勢,理想方案:JDK1.8中增加了一個平行計算,較理想執行緒數=CPU核數*2
  • IO密集型:涉及到大量的網路傳輸,不僅如此,和資料庫、和快取間的互動也涉及到IO,一旦發生IO,當前就會進入等待狀態,當IO結束,資料準備好後,才會繼續執行。理想方案:執行緒數=CPU核數/(1-阻塞係數),這個阻塞係數一般為0.8~0.9之間。

設計高併發原則

  1. **無狀態:**無狀態就是無需做持久化操作,有狀態就會涉及到資料同步,消耗記憶體消耗寬頻同時還會涉及到鎖的操作,影響快速擴容。
  2. **粒度化:**讀寫分離也好,應用服務化也好就是為了控制之間的依賴,分散請求提高併發效率,同時管理起來也比較清晰。
  3. **場景化:**合適的場景選擇合適的技術(訊息佇列、資料異構、快取銀彈、併發化)
    • 訊息佇列:解耦一些不需要同步呼叫的服務,或者訂閱一些關心的變化,還能流量削峰/緩衝,某些場景會有重複訊息(弊端),可以在業務層做防重和校對處理。
      流量削峰/緩衝
      RDBMS注重的是ACID,NOSQL注重的是CAP和BASE,一般是犧牲強一致性,而保證最終一致性。
      BASE
    • 資料異構:我們都知道系統都是由資料構成的,而資料的儲存位置和獲取的環境不一樣,速度也就不一樣。單表肯定比聯錶快,記憶體取肯定比磁碟取快;就像前面的文章有提過,也是我個人非常喜歡的一句話:時間換空間,空間換時間。所以可以根據實際場景和業務來設計,包括根據資料的權重犧牲一部分的資源來提高效率,例如:聯表可以考慮資料冗餘,或者關鍵資料的獲取合併儲存。
    • 快取銀彈:快取對於讀取服務來說就是顆抗流量的特效武器。
      快取
    • 併發化:併發化的理論其實很簡單,把沒有依賴關係的資料並行獲取。可能不太好理解,例如:B依賴A C沒有依賴 D依賴B,那麼最好的方式就是A、C並行獲取,然後再獲取B,再是D。

附上設計例圖:

高併發

結語

關於例圖裡面的一些詳細示例以後再慢慢補充吧,說了淺談就是淺談,要有原則(別打我~~~)!
裡面的圖片用的是思維導圖Xmind做的。
推薦:淺談高可用和設計的一些原則(JAVA)
個人部落格~
簡書~

相關文章