天天看點

架構概述之架構演化、模式與核心要素架構模式架構核心要素

點選上方“芋道源碼”,選擇“設為星标”

管她前浪,還是後浪?

能浪的浪,才是好浪!

每天 8:55 更新文章,每天掉億點點頭發...

源碼精品專欄

  • 原創 | Java 2020 超神之路,很肝~
  • 中文詳細注釋的開源項目
  • RPC 架構 Dubbo 源碼解析
  • 消息中間件 RocketMQ 源碼解析
  • 資料庫中間件 Sharding-JDBC 和 MyCAT 源碼解析
  • 作業排程中間件 Elastic-Job 源碼解析
  • 分布式事務中間件 TCC-Transaction 源碼解析
  • Eureka 和 Hystrix 源碼解析
  • Java 并發源碼

架構演化發展曆程

    • 應用和資料分離
    • 使用應用伺服器叢集
    • 反向代理和CDN
    • 使用NoSQL和搜尋引擎
    • 分布式服務
  • 分層
  • 分布式
  • 緩存
  • 備援
  • 架構核心要素
    • 可用性
    • 擴充性
    • 架構演化發展曆程

      大型網站的技術挑戰主要來自于龐大的使用者,高并發的通路和海量的資料。

      初始階段

      大型網站都是從小型網站發展而來,小型網站最開始時沒有太多人通路,隻需要一台伺服器就綽綽有餘,這時的網站架構如圖所示。
      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      應用和資料分離

      随着業務的發展,一台伺服器逐漸不能滿足需求:越來越多的使用者通路導緻性能越來越差,越來越多的資料導緻存儲空間不足。這時就需要将應用和資料分離。

      應用和資料分離後整個網站使用三台伺服器:應用伺服器、檔案伺服器和資料庫伺服器,如圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      這三台伺服器對硬體資源的要求各不相同,應用伺服器需要處理大量的業務邏輯,是以需要更快更強大的CPU;資料庫伺服器需要快速磁盤檢索和資料緩存,是以需要更快的硬碟和更大的記憶體;檔案伺服器需要存儲大量使用者上傳的檔案,是以需要更大的硬碟 。

      使用緩存

      随着使用者逐漸增多,網站又一次面臨挑戰:資料庫壓力太大導緻通路延遲,進而影響整個網站的性能,使用者體驗受到影響。

      網站通路遵循二八定律:80%的業務通路集中在20%的資料上。既然大部分的業務通路集中在一小部分資料上,那麼如果把這一小部分資料緩存在記憶體中,是不是就可以減少資料庫的通路壓力,提高整個網站的資料通路速度,改善資料庫的寫入性能了呢?

      網站使用的緩存可以分為兩種:緩存在應用伺服器上的本地緩存和緩存在專門的分布式緩存伺服器上的遠端緩存。本地緩存的通路速度更快一些,但是受應用伺服器記憶體限制,其緩存資料量有限,而且會出現和應用程式争用記憶體的情況。遠端分布式緩存可以使用叢集的方式,部署大記憶體的伺服器作為專門的緩存伺服器,可以在理論上做到不受記憶體容量限制的緩存服務 ,如圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      使用應用伺服器叢集

      使用緩存後,資料通路壓力得到有效緩解,但是單一應用伺服器能夠處理的請求連接配接有限,在網站通路高峰期,應用伺服器成為整個網站的瓶頸。

      使用叢集是解決高并發、海量資料問題的常用手段。當一台伺服器的處理能力、存儲空間不足時,不要企圖去換更強大的伺服器,對大型網站而言,不管多麼強大的伺服器,都滿足不了網站持續增長的業務需求。這種情況下,更恰當的做法是增加一台伺服器分擔原有伺服器的通路及存儲壓力。

      隻要能通過增加一台伺服器的方式改善負載壓力,就可以以同樣的方式持續增加伺服器不斷改善系統性能,進而實作系統的可伸縮性。應用伺服器叢集是可伸縮叢集架構設計中較為簡單成熟的一種,如圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      通過負載均衡排程伺服器,可将來自使用者浏覽器的通路請求分發到應用伺服器叢集中的任何一台伺服器上,如果有更多的使用者,就在叢集中加入更多的應用伺服器 ,使應用伺服器的負載壓力不再成為整個網站的瓶頸。

      讀寫分離

      網站在使用緩存後,使絕大部分資料讀操作通路都可以不通過資料庫就能完成,但是仍有一部分讀操作和全部的寫操作需要通路資料庫,在網站的使用者達到一定規模後,資料庫因為負載壓力過高而成為網站的瓶頸。

      目前大部分的主流資料庫都提供主從熱備功能,通過配置兩台資料庫主從關系,可以将一台資料庫伺服器的資料更新同步到另一台伺服器上。網站利用資料庫的這一功能,實作資料庫讀寫分離,進而改善資料庫負載壓力,如圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      應用伺服器在寫資料的時候,通路主資料庫,主資料庫通過主從複制機制将資料更新同步到從資料庫,這樣當應用伺服器讀資料的時候,就可以通過從資料庫獲得資料。為了便于應用程式通路讀寫分離後的資料庫,通常在應用伺服器端使用專門的資料通路子產品,使資料庫讀寫分離對應用透明。

      反向代理和CDN

      随着業務不斷發展,使用者規模越來越大,不同地區的使用者通路網站時,速度差别也極大。為了提供更好的使用者體驗,網站需要加速網站通路速度。主要手段有使用CDN和反向代理,如圖所示。
      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      CDN和反向代理的基本原理都是緩存,差別在于CDN部署在網絡提供商的機房,使使用者在請求網站服務時,可以從距離自己最近的網絡提供商機房擷取資料;而反向代理則部署在網站的中心機房,當使用者請求到達中心機房後,首先通路的伺服器是反向代理伺服器,如果反向代理伺服器中緩存着使用者請求的資源,就将其直接傳回給使用者。

      使用分布式檔案系統和分布式資料庫系統

      資料庫經過讀寫分離後,從一台伺服器拆分成兩台伺服器,但是随着網站業務的發展依然不能滿足需求,這時需要使用分布式資料庫。檔案系統也是一樣,需要使用分布式檔案系統,如圖所示。
      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      分布式資料庫是網站資料庫拆分的最後手段,隻有在單表資料規模非常龐大的時候才使用。不到不得已時,網站更常用的資料庫拆分手段是業務分庫,将不同業務的資料庫部署在不同的實體伺服器上。

      使用NoSQL和搜尋引擎

      随着網站業務越來越複雜,對資料存儲和檢索的需求也越來越複雜,網站需要采用一些非關系資料庫技術如NoSQL和非資料庫查詢技術如搜尋引擎,如圖所示。
      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      業務拆分

      大型網站為了應對日益複雜的業務場景,通過使用分而治之的手段将整個網站業務分成不同的産品線。具體到技術上,**将一個網站拆分成許多不同的應用,每個應用獨立部署維護。應用之間可以通過一個超連結建立關系(在首頁上的導航連結每個都指向不同的應用位址),也可以通過消息隊列進行資料分發,當然最多的還是通過通路同一個資料存儲系統來構成一個關聯的完整系
      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      分布式服務

      随着業務拆分越來越小,存儲系統越來越龐大,應用系統的整體複雜度呈指數級增加,部署維護越來越困難。

      既然每一個應用系統都需要執行許多相同的業務操作,比如使用者管理、商品管理等,那麼可以将這些共用的業務提取出來,獨立部署。由這些可複用的業務連接配接資料庫,提供共用業務服務,而應用系統隻需要管理使用者界面,通過分布式服務調用共用業務服務完成具體業務操作 ,如圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      大型網站的架構演化到這裡,基本上大多數的技術問題都得以解決。

      架構模式

      為了解決應用系統面臨的高并發通路、海量資料處理、高可靠運作等一系列問題與挑戰,大型網際網路公司在實踐中提出了許多解決方案,以實作高性能、高可用、易伸縮、可擴充、安全等各種技術架構目标。這些解決方案又被更多公司重複使用,進而逐漸形成架構模式。

      分層

      分層是企業應用系統中最常見的一種架構模式,将系統在橫向次元上切分成幾個部分,每個部分負責一部分相對比較單一的職責,然後通過上層對下層的依賴和調用組成一個完整的系統。

      在網站架構中,通常将應用系統分為應用層、服務層、資料層,如下圖所示。

      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      通過分層,可以更好地将一個龐大的軟體系統切分成不同的部分,便于分工合作開發和維護。各層之間具有一定的獨立性,隻要維持調用接口不變,各層可以根據具體問題獨立演化發展而不需要其他層必須做出相應調整。

      但是分層架構也有一些挑戰,就是必須合理規劃層次邊界和接口,在開發過程中,嚴格遵循分層架構的限制,禁止跨層調用及逆向調用。 在實踐中,大的分層結構内部還可以繼續分層。

      分層架構是邏輯上的,三層結構可以部署在同一個實體機器上。但是随着網站業務的發展,必然需要對已經分層的子產品分離部署,使網站擁有更多的計算資源以應對越來越多的使用者通路。

      分割

      分層是将軟體在橫向方面進行切分,分割則是在縱向方面對軟體進行切分。

      網站越大,功能越複雜,服務和資料處理的種類也越多。将這些不同的功能和服務分割開來,包裝成高内聚低耦合的子產品單元,一方面有助于軟體的開發和維護;另一方面,便于不同子產品的分布式部署,提高網站的并發處理能力和功能擴充能力。

      大型網站分割的粒度可能會很小。比如在應用層,将不同業務進行分割,例如将購物、論壇、搜尋、廣告分割成不同的應用,由獨立的團隊負責,部署在不同的伺服器上。

      分布式

      對于大型網站,分層和分割的一個主要目的是為了切分後的子產品便于分布式部署,即将不同子產品部署在不同的伺服器上,通過遠端調用協同工作 。分布式意味着可以使用更多的資源完成同樣的功能,能夠處理的并發通路和資料量也更大。

      但分布式在解決網站高并發問題的同時也帶來了其他問題。典型的有下面幾點:

      1. 意味着服務調用必須通過網絡,這可能會對性能造成比較嚴重的影響。
      2. 伺服器越多,當機的機率也就越大,造成的服務不可用可能會導緻很多應用不可通路,使網站可用性降低。
      3. 資料在分布式的環境中保持資料一緻性非常困難,分布式事務也難以保證。
      4. 系統依賴錯綜複雜,開發管理維護困難。
      是以分布式設計要根據具體情況量力而行。常用的分布式方案有:分布式服務、分布式資料庫、分布式計算、分布式配置、分布式鎖和分布式檔案系統等。

      叢集

      使用分布式雖然已經将分層和分割後的子產品獨立部署,但是對于使用者通路集中的子產品,還需要将獨立部署的伺服器叢集化,即多台伺服器部署相同應用構成一個叢集,通過負載均衡裝置共同對外提供服務。

      因為伺服器叢集有更多伺服器提供相同服務,是以可以提供更好的并發性,當有更多使用者通路的時候,隻需要向叢集中加入新的機器即可。同時當某台伺服器發生故障時,負載均衡裝置或者系統的失效轉移機制會将請求轉發到叢集中其他伺服器上,提高系統的可用性。

      緩存

      緩存就是将資料存放在距離計算最近的位置以加快處理速度。緩存是改善軟體性能的第一手段,在複雜的軟體設計中,緩存幾乎無處不在。比如常見的反向代理、Redis(未開啟持久化)、CDN等。

      使用緩存有兩個前提條件,一是資料通路熱點不均衡,某些資料會被更頻繁的通路,這些資料應該放在緩存中;二是資料在某個時間段内有效,不會很快過期,否則緩存的資料就會因已經失效而産生髒讀,影響結果的正确性 。

      緩存除了可以加快資料通路速度,還可以減輕後端應用和資料存儲的負載壓力 ,網站資料庫幾乎都是按照有緩存的前提進行負載能力設計的。

      異步

      應用系統的一個重要目标是降低耦合性。系統解耦的手段除了前面提到的分層、分割、分布式等,還有一個重要手段是異步,業務之間的消息傳遞不是同步調用,而是将一個業務操作分成多個階段,每個階段之間通過共享資料的方式異步執行進行協作。

      異步架構是典型的生産者消費者模式,兩者不存在直接調用,隻要保持資料結構不變,彼此功能實作可以随意變化而不互相影響,這對網站擴充新功能非常便利。 除此之外,使用異步消息隊列還有如下優點:

      • 提高系統可用性。 消費者伺服器發生故障,資料會在消息隊列伺服器中存儲堆積,生産者伺服器可以繼續處理業務請求,系統整體表現無故障。消費者伺服器恢複正常後,繼續處理消息隊列中的資料。
      • 加快網站響應速度。 處在業務處理前端的生産者伺服器在處理完業務請求後,将資料寫入消息隊列,不需要等待消費者伺服器處理就可以傳回,響應延遲減少。
      • 消除并發通路高峰。 使用者通路網站是随機的,存在通路高峰和低谷。使用消息隊列将突然增加的通路請求資料放入消息隊列中,等待消費者伺服器依次處理,就不會對整個網站負載造成太大壓力。
      但需要注意的是,使用異步方式處理業務可能會對使用者體驗、業務流程造成影響,需要網站産品設計方面的支援。

      備援

      網站需要7×24小時連續運作,但是伺服器随時可能出現故障,特别是伺服器規模比較大時,出現某台伺服器當機是必然事件。要想保證在伺服器當機的情況下網站依然可以繼續服務,不丢失資料,就需要一定程度的伺服器備援運作,資料備援備份,這樣當某台伺服器當機時,可以将其上的服務和資料通路轉移到其他機器上。

      通路和負載很小的服務也必須部署至少兩台伺服器構成一個叢集,其目的就是通過備援實作服務高可用。資料庫除了定期存檔進行冷備份外,還需要對資料庫進行主從分離,實時同步實作熱備份。

      自動化與安全

      目前應用系統的自動化架構設計主要集中在釋出運維方面。包括自動化釋出、自動化代碼管理、自動化測試、自動化安全監測、自動化部署、自動化監控、自動化告警、自動化失效轉移與恢複、自動化降級和自動化配置設定資源等。

      系統在安全架構方面也積累了許多模式:通過密碼和手機校驗碼進行身份認證;登入、交易等操作需要對網絡通信進行加密,網站伺服器上存儲的敏感資料如使用者資訊等也進行加密處理;為了防止機器人程式濫用網絡資源攻擊網站,網站使用驗證碼進行識别;對于常見的用于攻擊網站的XSS攻擊、SQL注入、進行編碼轉換等相應處理;對于垃圾資訊、敏感資訊進行過濾;對交易轉賬等重要操作根據交易模式和交易資訊進行風險控制。

      架構核心要素

      關于什麼是架構,維基百科是這樣定義的:“有關軟體整體結構與元件的抽象描述,用于指導大型軟體系統各個方面的設計”。

      一般說來,除了功能需求外,軟體架構還需要關注性能、可用性、伸縮性、擴充性和安全性這5個要素。

      性能

      性能是網站的一個重要名額,任何軟體架構設計方案都必須考慮可能會帶來的性能問題。也正是因為性能問題幾乎無處不在,是以優化網站性能的手段也非常多,主要的方式可以總結如下:
      • 浏覽器:浏覽器緩存、使用頁面壓縮、合理布局頁面、減少Cookie傳輸等
      • CDN和反向代理
      • 本地緩存和分布式緩存
      • 異步消息隊列
      • 應用層:伺服器叢集
      • 代碼層:多線程 、改善記憶體管理等
      • 資料層:索引、緩存、SQL優化 等,以及合理使用NoSQL資料庫

      可用性

      網站高可用的主要手段是備援,應用部署在多台伺服器上同時提供通路,資料存儲在多台伺服器上互相備份,任何一台伺服器當機都不會影響應用的整體可用,也不會導緻資料丢失。

      對于應用伺服器而言,多台應用伺服器通過負載均衡裝置組成一個叢集共同對外提供服務,任何一台伺服器當機,隻需把請求切換到其他伺服器即可,但是一個前提條件是應用伺服器上不能儲存請求的會話資訊。

      對于存儲伺服器,需要對資料進行實時備份,當伺服器當機時需要将資料通路轉移到可用的伺服器上,并進行資料恢複以保證繼續有伺服器當機的時候資料依然可用。

      除了運作環境,網站的高可用還需要軟體開發過程的品質保證。通過預釋出驗證、自動化測試、自動化釋出、灰階釋出等手段,減少将故障引入線上環境的可能。

      伸縮性

      衡量架構伸縮性的主要标準有:是否可以用多台伺服器建構叢集,是否容易向叢集中添加新的伺服器,加入新的伺服器後是否可以提供和原來的伺服器無差别的服務,叢集中可容納的總的伺服器數量是否有限制。

      對于應用伺服器叢集,通過使用合适的負載均衡裝置就可以向叢集中不斷加入伺服器。對于緩存伺服器叢集,需要使用高效的緩存路由算法,避免加入新伺服器導緻路由大面積失效。關系資料庫很難做到大規模叢集的可伸縮性,是以關系資料庫的叢集伸縮性方案必須在資料庫之外實作,通過路由分區等手段将部署有多個資料庫的伺服器組成一個叢集。至于大部分NoSQL資料庫産品,由于其先天就是為海量資料而生,是以其對伸縮性的支援通常都非常好。

      擴充性

      衡量架構擴充性的主要标準就是不同産品之間是否很少耦合。在網站增加新的業務産品時,是否可以實作對現有産品透明無影響,不需要任何改動或者很少改動既有業務功能就可以上線新産品。

      網站可伸縮架構的主要手段是事件驅動架構和分布式服務。

      事件驅動架構在網站通常利用消息隊列實作,将使用者請求和其他業務事件構造成消息釋出到消息隊列,消息的處理者作為消費者從消息隊列中擷取消息進行處理。通過這種方式将消息産生和消息處理分離開來,可以透明地增加新的消息生産者任務或者新的消息消費者任務。

      分布式服務則是将業務和可複用服務分離開來,通過分布式服務架構調用。新增産品可以通過調用可複用的服務實作自身的業務邏輯,而對現有産品沒有任何影響。可複用服務更新變更的時候,也可以通過提供多版本服務對應用實作透明更新,不需要強制應用同步變更。

      安全性

      網站的安全架構就是保護網站不受惡意通路和攻擊,保護網站的重要資料不被竊取。衡量網站安全架構的标準就是針對現存和潛在的各種攻擊與竊密手段,是否有可靠的應對政策。

      歡迎加入我的知識星球,一起探讨架構,交流源碼。加入方式,長按下方二維碼噢:

      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      已在知識星球更新源碼解析如下:
      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      架構概述之架構演化、模式與核心要素架構模式架構核心要素
      架構概述之架構演化、模式與核心要素架構模式架構核心要素

      最近更新《芋道 SpringBoot 2.X 入門》系列,已經 20 餘篇,覆寫了 MyBatis、Redis、MongoDB、ES、分庫分表、讀寫分離、SpringMVC、Webflux、權限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能測試等等内容。

      提供近 3W 行代碼的 SpringBoot 示例,以及超 4W 行代碼的電商微服務項目。

      擷取方式:點“在看”,關注公衆号并回複 666 領取,更多内容陸續奉上。

      文章有幫助的話,在看,轉發吧。
      謝謝支援喲 (*^__^*)