大型項目架構演進過程及思考

来源:https://www.cnblogs.com/almm/archive/2019/10/08/11637418.html
-Advertisement-
Play Games

淘寶架構 我們以淘寶架構為例,瞭解下大型的電商項目的服務端的架構是怎樣,如圖所示 上面是一些安全體繫系統,如數據安全體系、應用安全體系、前端安全體系等。 中間是業務運營服務系統,如會員服務、商品服務、店鋪服務、交易服務等。 還有共用業務,如分散式數據層、數據分析服務、配置服務、數據搜索服務等。 最下 ...


淘寶架構

我們以淘寶架構為例,瞭解下大型的電商項目的服務端的架構是怎樣,如圖所示

上面是一些安全體繫系統,如數據安全體系、應用安全體系、前端安全體系等。
中間是業務運營服務系統,如會員服務、商品服務、店鋪服務、交易服務等。
還有共用業務,如分散式數據層、數據分析服務、配置服務、數據搜索服務等。
最下麵呢,是中間件服務,如MQS即隊列服務,OCS即緩存服務等。

圖中也有一些看不到,例如高可用的一個體現,實現雙機房容災和異地機房單元化部署,為淘寶業務提供穩定、高效和易於維護的基礎架構支撐。

這是一個含金量非常高的架構,也是一個非常複雜而龐大的架構。當然這個也不是一天兩天演進成這樣的,也不是一上來就設計並開發成這樣高大上的架構的。

這邊就要說一下,小型公司要怎麼做呢?對很多創業公司而言,很難在初期就預估到流量十倍、百倍以及千倍以後網站架構會是什麼樣的一個狀況。同時,如果系統初期就設計一個千萬級併發的流量架構,很難有公司可以支撐這個成本。

因此,一個大型服務系統都是從小一步一步走過來的,在每個階段,找到對應該階段網站架構所面臨的問題,然後在不斷解決這些問題,在這個過程中整個架構會一直演進。
那我們來一起看一下。

單伺服器-俗稱all in one

從一個小網站說起。一臺伺服器也就足夠了。文件伺服器,資料庫,還有應用都部署在一臺機器,俗稱ALL IN ONE

隨著我們用戶越來越多,訪問越來越大,硬碟,CPU,記憶體等都開始吃緊。一臺伺服器已經滿足不了。這個時候看一下下一步演進

數據服務與應用服務分離

 

 

 

我們將數據服務和應用服務分離,給應用伺服器配置更好的 CPU,記憶體。而給數據伺服器配置更好更大的硬碟。

分離之後提高一定的可用性,例如Files Server掛了,我們還是可以操作應用和資料庫等。
隨著訪問qps越來越高,降低介面訪問時間,提高服務性能和併發,成為了我們下一個目標,發現有很多業務數據不需要每次都從資料庫獲取。

使用緩存,包括本地緩存,遠程緩存,遠程分散式緩存

 

 

 

因為 80% 的業務訪問都集中在 20% 的數據上,也就是我們經常說的28法則。如果我們能將這部分數據緩存下來,性能一下子就上來了。而緩存又分為兩種:本地緩存和遠程緩存緩存,以及遠程分散式緩存,我們這裡面的遠程緩存圖上畫的是分散式的緩存集群(Cluster)。

思考的點

  1. .          具有哪種業務特點數據使用緩存?
  2. .          具有哪種業務特點的數據使用本地緩存?
  3. .          具有哪種務特點的數據使用遠程緩存?
  4. .          分散式緩存在擴容時候會碰到什麼問題?如何解決?分散式緩存的演算法都有哪幾種?各有什麼優缺點?

這個時候隨著訪問qps的提高,伺服器的處理能力會成為瓶頸。雖然是可以通過購買更強大的硬體,但總會有上限,而且這個到後期成本就是指數級增長了,這時,我們就需要伺服器的集群。需要使我們的伺服器可以橫向擴展,這時,就必須加個新東西:負載均衡調度伺服器。

使用負載均衡,進行伺服器集群

 

 


增加了負載均衡,伺服器集群之後,我們可以橫向擴展伺服器,解決了伺服器處理能力的瓶頸。

思考的點

  1. .          負載均衡的調度策略都有哪些?
  2. .          各有什麼優缺點?
  3. .          各適合什麼場景?

打個比方,我們有輪詢,權重,地址散列,地址散列又分為原ip地址散列hash,目標ip地址散列hash,最少連接,加權最少連接,還有繼續升級的很多種策略......我們一起來分析一下

典型負載均衡策略分析

  1. .          輪詢:優點:實現簡單,缺點:不考慮每台伺服器處理能力
  2. .          權重:優點:考慮了伺服器處理能力的不同
  3. .          地址散列:優點:能實現同一個用戶訪問同一個伺服器
  4. .          最少連接:優點:使集群中各個伺服器負載更加均勻
  5. .          加權最少連接:在最少連接的基礎上,為每台伺服器加上權值。演算法為(活動連接數*256+非活動連接數)/權重,計算出來的值小的伺服器優先被選擇。

繼續引出問題的場景:

我們的登錄的時候登錄了A伺服器,session信息存儲到A伺服器上了,假設我們使用的負載均衡策略是ip hash,那麼登錄信息還可以從A伺服器上訪問,但是這個有可能造成某些伺服器壓力過大,某些伺服器又沒有什麼壓力,這個時候壓力過大的機器(包括網卡帶寬)有可能成為瓶頸,並且請求不夠分散。

這時候我們使用輪詢或者最小連接負載均衡策略,就導致了,第一次訪問A伺服器,第二次可能訪問到B伺服器,這個時候存儲在A伺服器上的session信息在B伺服器上讀取不到。

Session管理-Session Sticky粘滯會話:

 

 

 

打個比方就是如果我們每次吃飯都要保證我們用的是自己的碗筷,而只要我們在一家飯店裡存著我們的碗筷,只要我們每次去這家飯店吃飯就好了。

對於同一個連接中的數據包,負載均衡會將其轉發至後端固定的伺服器進行處理。

解決了我們session共用的問題,但是它有什麼缺點呢?

  1. .          一臺伺服器運行的服務掛掉,或者重啟,上面的 session 都沒了
  2. .          負載均衡器成了有狀態的機器,為以後實現容災造成了羈絆

Session管理-Session 複製

 

就像我們在所有的飯店裡都存一份自己的碗筷。我們隨意去哪一家飯店吃飯都OK,不適合做大規模集群,適合機器不多的情況。

解決了我們session共用的問題,但是它有什麼缺點呢?

  1. .          應用伺服器間帶寬問題,因為需要不斷同步session數據
  2. .          大量用戶線上時,伺服器占用記憶體過多

Session管理-基於Cookie

 

 

 

打個比方,就是我們每次去飯店吃飯,都自己帶著自己的碗筷。

解決了我們session共用的問題,但是它有什麼缺點呢?

  1. .          cookie 的長度限制
  2. .          cookie存於瀏覽器,安全性是一個問題

Session管理-Session 伺服器

 

 

 

打個比方,就是我們的碗筷都存在了一個龐大的櫥櫃里,我們去任何一家飯店吃飯,都可以從櫥櫃中拿到屬於我們自己的碗筷。

解決了我們session共用的問題,這種方案需要思考哪些問題呢?

  1. .          保證 session 伺服器的可用性,session伺服器單點如何解決?
  2. .          我們在寫應用時需要做調整存儲session的業務邏輯

打個比方,我們為了提高session server的可用性,可以繼續給session server做集群

中間總結

所以說,網站架構在遇到某些指標瓶頸時,演進的過程中,都有哪些解決方案,他們都有什麼優缺點?業務功能上如何取捨?如何做出選擇?這個過程才是最重要的。

在解決了橫向擴展應用伺服器之後,那我們繼續~~

繼續回到目前架構圖

 

 

 

資料庫的讀及寫操作都還需要經過資料庫。當用戶量達到一定量,資料庫將會成為瓶頸。那我們如何來解決呢?

資料庫讀寫分離

 

 

 

使用資料庫提供的熱備功能,將所有的讀操作引入slave 伺服器,因為資料庫的讀寫分離了,所以,我們的應用程式也得做相應的變化。我們實現一個數據訪問模塊(圖中的data access module)使上層寫代碼的人不知道讀寫分離的存在。這樣多數據源讀寫分離就對業務代碼沒有了侵入。這裡就引出了代碼層次的演變

思考的點

  1. .          如何支持多數據源?
  2. .          如何封裝對業務沒有侵入?
  3. .          如何使用目前業務的ORM框架完成主從讀寫分離?是否需要更換ORM模型?ORM模型之間各有什麼優缺點?
  4. .          如何取捨?

資料庫讀寫分離會遇到如下問題:

  1. .          在master和slave複製的時候,考慮延時問題、資料庫的支持、複製條件的支持。
  2. .          當為了提高可用性,將資料庫分機房後,跨機房傳輸同步數據,這個更是問題。
  3. .          應用對於數據源的路由問題

使用反向代理和 CDN 加速網站響應

 

 

 

使用 CDN 可以很好的解決不同的地區的訪問速度問題,反向代理則在伺服器機房中緩存用戶資源。

訪問量越來越大,我們文件伺服器也出現了瓶頸。

分散式文件系統

 

 

 

思考的點

  1. .          分散式文件系統如何不影響已部署線上上的業務訪問?不能讓某個圖片突然訪問不到呀
  2. .          是否需要業務部門清洗數據?
  3. .          是否需要重新做功能變數名稱解析?

這個時候資料庫又出現了瓶頸

數據垂直拆分

 

 

 

資料庫專庫專用,如圖Products、Users、Deal庫。

解決寫數據時,併發,量大的問題。

思考的點

  1. .          跨業務的事務?如何解決?使用分散式事務、去掉事務或不追求強事務
  2. .          應用的配置項多了
  3. .          如何跨庫進行數據的join操作

這個時候,某個業務的數據表的數據量或者更新量達到了單個資料庫的瓶頸

數據水平拆分

 

 

 

如圖,我們把User拆成了User1和User2,將同一個表的數據拆分到兩個資料庫中,解決了單資料庫的瓶頸。

思考的點

  1. .          水平拆分的策略都有哪些?各有什麼優缺點?
  2. .          水平拆分的時候如何清洗數據?
  3. .          SQL 的路由問題,需要知道某個 User 在哪個資料庫上。
  4. .          主鍵的策略會有不同。
  5. .          假設我們系統中需要查詢2017年4月份已經下單過的用戶名的明細,而這些用戶分佈在user1和user2上,我們後臺運營系統在展示時如何分頁?

這個時候,公司對外部做了流量導入,我們應用中的搜索量飆升,繼續演進

拆分搜索引擎

 

 

 

使用搜索引擎,解決數據查詢問題。部分場景可使用 NoSQL 提高性能,開發數據統一訪問模塊,解決上層應用開發的數據源問題。如圖data access module 可以訪問資料庫,搜索引擎,NoSQL

最後總結

這個只是一個舉例演示,各個服務的技術架構是需要根據自己業務特點進行優化和演進的,所以大家的過程也不完全相同。

最後的這個也不是完美的,例如負載均衡還是一個單點,也需要集群,我們的這個架構呢也只是冰山一角,滄海一粟。在架構演進的過程中,還要考慮系統的安全性、數據分析、監控、反作弊等等......,同時繼續發展呢,SOA架構、服務化、消息隊列、任務調度、多機房等等… ...

從剛纔對架構演進的講解,也可以看出來,所有大型項目的架構和代碼,都是這麼一步一步的根據實際的業務場景,和發展情況發展演變而來的,在不同的階段,會使用的不同的技術,不同的架構來解決實際的問題,所以說,高大上的項目技術架構和開發設計實現不是一蹴而就的。

正是所謂的萬丈高樓平地起。在架構演進的過程中,小到核心模塊代碼,大到核心架構,都會不斷演進的,這個過程值得我們去深入學習和思考。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 參考:https://blog.csdn.net/xxjmlgb/article/details/49467717 ...
  • 解構:ES6允許按照一定模式,從數組和對象中提取值,對變數進行賦值。 對象的解構與數組有一個重要的不同。數組的元素是按次序排列的,變數的取值由他的位置決定;而對象的屬性沒有次序,變數必須與屬性同名,才能取到正確的值。 變數解構賦值的用途:交換變數的值,從函數返回多個值,函數參數的定義,提取JSON數 ...
  • Let:用來聲明變數,但是所聲明的變數,只在let命令所在的代碼塊內生效。 變數提升:變數可以在聲明之前使用,值為undefined。 暫時性死區:在代碼塊內,使用let命令聲明變數之前,該變數都是不可用的。 不允許重覆聲明:let不允許在相同作用域內,重覆聲明同一變數。 Const:const聲明 ...
  • 本文僅限於入門級,沒有成規模製作,希望能對你有所幫助。 因為在開發多個項目中可能會用到同一個組件,那麼我們通過複製粘貼的形式更新,無異於是笨拙的,我們可以通過上傳到npm後,不斷迭代npm包來實現更新。 前期準備 初始化project 這裡我們使用 來初始化一個vue項目。 or 首先我們來開發一個 ...
  • 垃圾分類,一般是指按一定規定或標准將垃圾分類儲存、分類投放和分類搬運,從而轉變成公共資源的一系列活動的總稱。分類的目的是提高垃圾的資源價值和經濟價值,力爭物盡其用。垃圾在分類儲存階段屬於公眾的私有品,垃圾經公眾分類投放後成為公眾所在小區或社區的區域性準公共資源,垃圾分類搬運到垃圾集中點或轉運站後成... ...
  • 一.開通QQ服務 "點我進入QQ推廣官網" 然後點擊 後面自己看中文 二.頁面a標簽 三.js實現 ...
  • 什麼是微服務?為什麼會有微服務?讓我們帶著這些疑問開始我們的探索。 我們先看下維基百科和百度百科給出的定義: 維基百科:2014年,Martin Fowler 與 James Lewis 共同提出了微服務的概念,定義了微服務是由以單一應用程式構成的小服務,自己擁有自己的行程與輕量化處理,服務依業務功 ...
  • 0--前言 spring cloud的服務註冊中心,該選擇誰?在選擇前,我們首先需要來瞭解下分散式的CAP定理: 所謂CAP,是指: Consistency:一致性;就是在分散式系統中的所有數據備份,在同一時刻是否同樣的值 Availability:可用性;就是負載過大後,集群整體是否還能響應客戶端 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...