天天看點

Java項目架構的演變

文章目錄

   系統架構演化曆程

       單體架構

       應用服務和資料服務分離

       緩存的使用

       叢集的使用

       資料庫讀寫分離

       反向代理和CDN加速

       分布式檔案和分布式資料庫

       NoSql和搜尋引擎

       業務拆分

       分布式服務

 現在出去找工作如果不會點分布式和微服務相關的内容,都不太好更面試官扯蛋。但這些架構也不是突然就出現的,而是經過不但演變才出現及流行起來的,本文就給大家來梳理下java項目架構的演變曆程。

系統架構演化曆程

單體架構

 大型網站都是從小型網站發展而來的,網站架構也是一樣,是從小型網站架構逐漸演化而來的,小型網站最開始沒有太多人通路,隻需要一台伺服器就綽綽有餘了,這時的架構如下:

Java項目架構的演變

 應用程式、資料庫、檔案等所有的資源都在一台伺服器上,通常伺服器作業系統使用Linux、應用程式使用java或者其他語句,然後部署在Apache或者Nginx上。資料庫使用MySQL,使用開源的技術實作,然後部署在一台廉價的伺服器上就開始了網站的發展之路。

應用服務和資料服務分離

 好景不長,随着公司業務的發展,一台服務逐漸滿足不了需求,越來越多的使用者通路導緻性能越來越差,資料存儲空間開始不足,這時我們需要将應用和資料分離,分離後開始使用三台伺服器:應用伺服器、檔案伺服器、資料庫伺服器。如圖:

Java項目架構的演變

 應用和資料分離後,不同特性的伺服器承擔着不同的服務角色,網站的并發處理能力和資料存儲空間都得到了很大的改善,支援網站業務進一步發展,但是随着使用者逐漸增多,資料庫壓力越來越大,通路延遲,進而影響整個網站的性能,此時需要進一步優化。

緩存的使用

 網站通路有個著名的二八定律,即80%的業務集中通路在20%的資料上,如果我們将這一小部分的資料緩存在記憶體中,能夠很好的減少資料庫的通路壓力,提高整個網站的資料通路速度。

Java項目架構的演變

 緩存常用的元件可以是Redis,ehcache等

叢集的使用

 緩存解決了資料庫通路量比較大的問題,但是并不能解決随着業務增多造成的伺服器并發壓力大的問題,這時我們需要增加一台應用伺服器來分擔原來伺服器的通路壓力和存儲壓力。如圖:

Java項目架構的演變

 通過負載均衡排程伺服器,可将來自使用者的通路請求分發到應用伺服器中的任何一台伺服器中,這樣多台伺服器就分擔了原來一台伺服器的壓力,我們隻需要注意會話的一緻性就可以了。

資料庫讀寫分離

 系統正常運作了一段時間後,雖然加的有緩存,使絕大多數的資料庫操作可以不通過資料庫就能完成,但是任然有一部分的操作(緩存通路不命中,緩存過期)和全部的寫操作需要通路資料庫,當使用者達到一定規模後,資料庫因為負載壓力過大還是會成為系統的瓶頸,

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

Java項目架構的演變

 mysql的讀寫分離可以通過自身自帶的從主複制實作,Oracle的話可以通過阿裡巴巴的mycat元件來實作。

反向代理和CDN加速

 為了應付複雜的網絡環境和不同地區使用者的通路,通過CDN和反向代理加快使用者通路的速度,同時減輕後端伺服器的負載壓力。CDN與反向代理的基本原理都是緩存。CDN部署在網絡提供商的機房。使用者請求到來的時候從距離自己最近的網絡提供商機房擷取資料,而反向代理則部署在網站的中心機房中,請求帶來的時候先去反向代理伺服器中檢視請求資源,如果有則直接傳回。如圖:

Java項目架構的演變

 使用CDN和反向代理的目的都是盡早傳回資料給使用者,一方面加快使用者的通路速度,另一方面也減輕後端伺服器的負載壓力。

分布式檔案和分布式資料庫

 任何強大的單一伺服器都滿足不了大型網站持續增長的業務需求。資料庫經過讀寫分離後,從一台伺服器拆分成兩天伺服器,但是随着業務的增長後面依然不能滿足需求,這時我們需要使用分布式資料庫,同時檔案系統也一樣,需要使用分布式檔案系統。

 分布式資料庫是資料庫拆分的最後的手段,隻有在表單資料規模非常龐大的時候才使用,不到不得已時,我們更常用的手段是業務分庫,将不同的業務資料部署在不同的實體伺服器上。

Java項目架構的演變

NoSql和搜尋引擎

 随着業務越來越複雜,對資料存儲和檢索的需求也越來越複雜,這時一些NoSQL(Reids,HBase,mongodb)資料庫技術和搜尋引擎(Solr,Elasticsearch)的時候就顯得很有必要。如下圖:

Java項目架構的演變

 NoSQL和搜尋引擎對可伸縮的分布式特性具有更好的支援,應用伺服器通過一個統一的資料通路子產品通路各種資料,減輕應用程式管理諸多資料源的麻煩。

業務拆分

 當通路量達到一定規模的時候我們可以通過分而治之的手段将整個系統的業務分成不同的産品線,例如我們将系統的首頁,商鋪,訂單,買家,賣家,支付,訂單等拆分成不同的産品線。

 具體到技術實作上,也可以根據産品線劃分,将一個網站拆分成許多不同的應用,每個應用獨立部署維護,應用之間通過RPC架構(dubbo,webService,httpClient…)建立連接配接,也可以通過消息隊列實作異步分發處理。來構成一個完整的系統,如下圖:

Java項目架構的演變

分布式服務

 随着業務拆分越來越小,存儲系統越來越龐大,應用系統的整體複雜度呈指數級增加,部署維護越來越困難,由于所有應用要和所有資料庫系統連接配接,最終導緻資料庫連接配接資源不足,拒絕服務。

   當服務越來越多時,服務URL配置管理變得非常困難,F5硬體負載均衡器的單點壓力也越來越大。

   當進一步發展,服務間依賴關系變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。

   接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器?

   服務多了,溝通成本也開始上升,調某個服務失敗該找誰?服務的參數都有什麼約定?

   一個服務有多個業務消費者,如何確定服務品質?

   随着服務的不停更新,總有些意想不到的事發生,比如cache寫錯了導緻記憶體溢出,故障不可避免,每次核心服務一挂,影響一大片,人心慌慌,如何控制故障的影響面?服務是否可以功能降級?或者資源劣化?

解決方案:公共的應用子產品被提取出來,部署在分布式伺服器上供應用伺服器調用。也就是我們将的分布式服務或者微服務。

微服務的設計原則參考此文:

https://dpb-bobokaoya-sm.blog.csdn.net/article/details/87305626