因用戶量、訪問量、數據量等不同,系統架構被分為了多個發展階段,為了解決不同階段業務所帶來的不同的技術問題,就有了以下系統架構演化歷程。
從單體到微服務,文字過於蒼白,上圖對比
1初始階段
業務發展初期,為了更快速滿足客戶需求,將所有業務功能模塊都放在一個系統中來實現。
優點就是快速響應,優先搶占市場份額。
在單體階段一般會使用到的網站架構模式是:分層模式
1.1分層模式
定義:將系統在橫向維度上切分成幾個部分,每部分的職責單一,上層對下層的依賴和調用組成一個完整的系統。
栗子:7層的網絡通信協議;計算機硬件、操作系統和應用系統;MVC三層架構等
原因(為什么要分層):分層結構對網站支持高並發和向分布式方向發展至關重要
約束:層次之間禁止 跨層次調用,逆向調用。
建議:在網站規模還很小的時候應該采用分層的架構。
一般單體的分層架構:
分層如分工,為的就是各施其職,但如何落地到開發層面呢?
通過按業務功能模塊進行分包分層開發
這樣做的目的是能更好的應對架構的演化過程,降低升級改造難度、風險、成本等。后續只需要對不同的業務模塊進行抽離,即可實現業務拆分。
1.2部署方式
通常服務器操作系統使用linux,前端使用nginx部署、業務端使用tomcat部署、數據存儲為MySQL數據庫、文件存儲(如:FastDFS)。
這時網站架構如圖:
隨着業務的發展,越來越多的用戶訪問導致性能越來越差,越來越多的數據導致存儲空間不足,當單台服務器無法滿足業務發展所需時,此時就要做業務的垂直拆分了??為時尚早!垂直拆分將在后續講到。這時應該按層進行分離,前端、應用和數據做分離,也稱為橫向拆分,這也是為什么一開始要做分層的原因。
2橫向拆分階段
按層進行分離,也成為橫向拆分。拆分后需要分別部署到四台服務器,但這四台服務器對硬件資源的要求各不相同,前置和應用服務器需要處理大量的業務邏輯,因此需要更快功能強大的CPU資源;數據庫服務器需要快速磁盤檢索和數據緩存,因此需要更快的硬盤和更大的內存;文件服務器需要存儲大量用戶上傳的文件,因此需要更大的硬盤。
這時網站架構如圖:
不同特性的服務器獨立使用一台服務器,使得網站的並發處理能力和數據存儲空間得到了很大的改善,支持網站業務進一步發展。但是隨着用戶逐漸增多,網站又一次面臨挑戰:數據庫壓力太大導致訪問延遲,進而影響整個網站的性能,用戶體驗受到影響。這時需要對網站架構進一步優化。
3緩存改善網站性能階段
加入本地緩存EhCache和Redis緩存服務器用於提升數據訪問速度,降低數據庫服務器的訪問壓力。
3.1緩存模式
定義:將數據存放在距離計算最近的位置以加快處理速度。
目的:提高系統性能
使用前提:
1. 數據訪問熱點不均衡,頻繁訪問的數據應該放在緩存
2. 數據在某個時間段內有效,短時間內不會過期的數據應該放在緩存
3. 一定時間內允許數據不一致,最終一致即可
4. 一定程度上允許數據不一致,也即是說部分數據丟失也不影響業務
每一層都有屬於自己的緩存,常用的幾種緩存:CDN緩存、nginx緩存、進程內緩存(Mybatis緩存,Spring MVC頁面緩存,EhCache數據緩存)、進程外緩存(Redis 分布式緩存)、數據庫緩存等等。
該階段引入緩存主要用於提高數據的訪問速度,降低數據訪問壓力。但單一的web服務器和業務服務器能夠處理的請求連接有限,在高並發場景成為整個系統的瓶頸。
4應用服務器集群階段
圖文結合更生動,先上圖
本階段和之前的階段唯一的區別在於:web服務器和應用服務器都采用集群模式,而集群必然就帶上了負載均衡。
該階段我們主要是分析集群模式和負載均衡。
4.1集群模式
定義:多台服務器部署相同應用構成一組相互獨立的計算機群。
作用:提高並發、提高可用性、提高擴展性
條件:無狀態服務
狀態化服務:服務器端一般都要保存請求的相關信息,每個請求可以默認地使用以前的請求信息。
無狀態服務:服務器端所能夠處理的過程必須全部來自於請求所攜帶的信息,以及其他服務器端自身所保存的、並且可以被所有請求所使用的公共信息。
有狀態服務還是無狀態服務,其判斷依據:來自相同發起者的兩個請求在服務器端是否具備上下文關系。
對於無狀態服務:天生適合集群。
對於有狀態服務:需要實現同一個用戶負載到不同服務器的請求結果一致,這里就涉及到session管理問題。
4.1.1session管理
最佳方案:session 服務器
最有效的方案是:有狀態服務=無狀態服務+有狀態的session服務,也即是將保存狀態的模塊抽離出來獨立部署、共同訪問。
一般情況可以使用redis 分布式緩存來實現共享session;
如果業務場景對session管理要求比較高,則利用獨立的session服務器共享session,同時集成單點登錄SSO、用戶服務等功能。
其他實現session管理的方案:
-
業務服務器之間做Session復制;
-
利用cookie記錄session,每次請求都帶有最新的session;
-
session綁定在服務器,通過負載均衡算法確保同一個ip每次訪問相同的服務器
4.2負載均衡
負載均衡顧名思義是:負載和均衡…………將用戶的請求均衡的發送到不同的服務器來做業務處理。
服務員上菜:負載均衡分類和常見算法
負載均衡還有很多使命,比如:
1. 自動剔除故障服務節點;
2. 自身設備高可用(如硬件負載F5,keepalive);
3. 逃生機制(如果所有節點不可用,可以重定向到其他可用站點);
4. 豐富的優化技術手段(如TCP優化,HTTP壓縮,SSL/TLS卸載,連接復用,連接數限制,用戶優先級等)
負載均衡是門大學問,有時間專門寫一個關於負載均衡的系列文章。
5數據庫讀寫分離階段
網站在使用緩存后,使絕大部分數據讀操作訪問都落在緩存中,但是仍然有一部分讀操作(緩存訪問不命中、緩存過期)和全部寫操作需要訪問數據庫,隨着網站用戶不斷增長,業務並發訪問增大,數據庫負載壓力也不斷增大,最終成為網站的瓶頸。此時此刻就要對數據庫動刀了。
業務服務器在寫數據時,訪問主數據庫,主數據庫(master)通過主從復制機制將數據同步到從數據庫(slave),這樣當應用服務器讀數據的時候,就可以通過從數據庫來獲取,從而實現數據庫的讀寫分離,提高數據庫的並發訪問。此時需要引入數據訪問模塊來實現數據庫讀寫分離對應用透明化。
6加速網站響應階段
隨着網站業務不斷發展,用戶規模越來越大,不同地區的用戶訪問網站時速度差別很大,此時需要加速網站響應。加速網站響應,是為了提供更好的用戶體驗,留住用戶。主要解決方案有CDN和反向代理。細心的會發現,上個階段已經加入了反向代理(負載web服務器集群),因此本階段主要是加入CDN更進一步提升訪問速度。
7全部服務分布式階段
任何強大的單一服務器都滿足不了大型網站持續增長的業務需求。數據庫經過讀寫分離后,依然不能滿足需求,這時需要使用分布式數據庫。文件系統也是一樣,需要使用分布式文件系統。
8提高數據檢索階段
隨着網站業務越來越復雜,數據量越來越大,對數據檢索需求也越來越復雜,網站需要采用非數據庫查詢技術來解決數據檢索慢的問題。如elastic search搜索引擎。對於檢索數據的訪問落在高速搜索引擎服務器中,極大的提高數據檢索響應速度。
9垂直拆分階段
雖然經歷了很多個階段,但是業務仍然是單體服務,只是做了橫向擴展,並沒有對單體服務進行拆分。單體應用隨着業務需求的迭代,功能的追加擴展,最終成為一個龐然大物。變得更加復雜,邏輯耦合嚴重,難以理解,團隊開發 人員職責不清,部署困難,回歸測試成本巨大,交付效率大大降低。
9.1總結單體應用缺點
-
代碼難以理解,導致代碼質量逐漸降低,復雜性逐漸增加,代碼難以被修改和重構,簡言之:屎山。
-
"屎山"懂得都懂,代碼量大耦合度高動一發亂全身,構建和部署耗時長,難以定位問題,大部分時間花費在解決代碼沖突上,導致開發效率極低,
-
可靠性差,一個bug可能會引起整個應用崩潰。
-
伸縮性差,單體只能按整體橫向擴展,無法分模塊垂直擴展,無法分團隊獨立開發部署;IO密集型模塊和CPU密集型模塊無法獨立升級和擴容。
-
高度耦合的單體工程使得邏輯邊界模糊不清,新業務需求開發任務無法有效分配到人,團隊人員職責不清晰,溝通成本增加。
-
技術棧受限於同一框架和語言,阻礙新技術的融入,也阻礙新鮮血液的流入,貧血的系統終將走向死亡。
龐大的東西要干嘛?拆!老城區阻礙城市的發展,拆!代表性文化老城區就不能拆了,所以拆的時候要注意點。
9.2概述
定義:垂直拆分階段是將系統在縱向維度上以功能和服務的不同進行切分,再包裝成高內聚、低耦合的模塊單元。
栗子:按業務進行分割:購物、論壇、搜索、廣告等。
垂直拆分分為兩種情況:
-
一是只拆分業務功能,數據庫不拆分;
- 二是業務功能和數據庫同時拆分。
前者相對后者來說更簡單,隨着業務的增長數據庫拆分也是遲早的事,但系統的復雜度也成倍增加。
9.3垂直拆分之業務拆分
小二上菜
按照功能模塊進行拆分,每個模塊獨立集群部署,使用相同的數據庫。
優點:快速增長時,以應用系統為中心共用數據庫的架構模式,業務系統間無需互相調用,也就不需要引入服務間遠程調用。
缺點:耦合度高(共用數據庫),數據庫會成為以后的瓶頸
在本階段同時引入了消息隊列,部分業務可以采用異步處理、數據擠壓在消息隊列中再慢慢消費等等。降低數據庫的並發訪問,在這個階段也帶來了很好的性能提升。
同時引入API網關,對請求做統一管理。API網關的基本功能包含了統一接入、協議適配、流量管理與容錯、以及安全防護,這四大基本功能構成了網關的核心功能。網關首要的功能是負責統一接入,然后將請求的協議轉換成內部的接口協議,在調用的過程中還要有限流、降級、熔斷等容錯的方式來保護網關的整體穩定,同時網關還要做到基本的安全防護(防刷控制),以及黑白名單(比如IP白名單)等基本安全措施。
9.4垂直拆分之業務和數據拆分
在業務拆分的基礎上加入數據庫拆分。和業務拆分一樣,數據庫按照業務功能模塊做相對應的進行拆分。當A業務想訪問B數據庫時,需要通過遠程調用來訪問B業務獲取數據,又因為B業務是集群服務,所以需要通過訪問LB來負載到B業務群。談到遠程服務調用,業務服務間通常采用RPC(TCP協議)或 Restful API(HTTP協議)來實現遠程調用。服務間除了通過遠程調用,還可以通過消息隊列來完成異步的服務間調用。
目前流行的分布式服務治理技術方案有:Dubbo 和 Spring Cloud,分別是RPC 和 Restful 兩種不同的解決方案。
10微服務階段
垂直拆分業務和數據階段是微服務的雛形,為微服務階段奠定了基礎。
所謂微服務架構風格是一種將單個應用程序開發為一組小型服務的方法,每個小服務運行在自己的進程中,並以輕量級的機制(通常是HTTP RESTful API)的方式進行通信,這些服務圍繞着業務能力所建立的,並且可以由完全自動化的部署機構獨立部署,這些服務的集中管理只有最低限度,可以用不同的編程語言編寫並使用不同的數據庫存儲技術。
——詹姆斯.里維斯 & 馬丁.弗勒
說白了微服務也是分布式系統,不同業務系統間通過服務接口相互對接形成一個大型分布式系統。比如我要對接第三方支付系統(如微信支付/支付寶支付),我先申請開通支付功能,再拿到他們提供的支付接口對接文檔,按照文檔來完成對接即可。分布式系統也不是什么高大上的東西,分布式系統是一組計算機系統一起工作,在終端用戶看來,就像一台計算機在工作一樣。只不過在這個過程中會因為產生很多新的問題,需要學習新的技術或思想來解決對應的問題罷了。不要在現在擁有海量學習資料的互聯網中迷失了方向,最終還是基礎最重要。
10.1微服務的優點
-
易於開發與維護
微服務相對小,易於理解;啟動時間短,開發效率高
-
獨立部署
一個微服務的修改不需要協調其它服務
-
伸縮性強
每個服務都可以在橫向和縱向上擴展;每個服務都可按硬件資源的需求進行獨立擴容
-
與組織結構相匹配
微服務架構可以更好將架構和組織相匹配;每個團隊獨立負責某些服務,獲得更高的生產力,也更容易擴大開發團隊
-
提高容錯性
一個服務的內存泄露並不會讓整個系統癱瘓
-
技術異構性
使用最適合該服務的技術;降低嘗試新技術的成本
10.2微服務的缺點
-
團隊溝通的過載
微服務架構降低了團隊管理的難度,但是卻不能降低團隊溝通的需求。研發人員需要確保一個服務中的更新不會破壞其它功能。我們在單體應用中也會發現類似問題,但是微服務架構的應用這個問題會更加明顯。
-
正式文檔的過載
每一個獨立的運行部件需要持續維護其規格和接口文檔,這些文檔是其它團隊使用這些部件的必要條件。
-
不一致性的應用
我們可以為每一個組件選擇不同的技術棧。這導致了不一致的應用設計和架構,而這會在更長期的運維期間增加系統維護成本。提煉代碼腳手架統一的快速開發環境,運維起來更容易,但並不是銀彈。
-
數據的復雜度
與單用戶系統相比,連接到分布式系統的數據庫是相當復雜和難以處理的,並且還有很多其他的數據源
-
DevOps的復雜度
我們需要擁有一支成熟的DevOps團隊去處理微服務架構的應用的復雜性。由於多個應用存在多個活動部件,這種復雜度需要有高水平的經驗。
-
增加了資源使用
運行這些微服務架構的應用的初始投資會比較大,因為所有微服務應都需要擁有他們自己的運行容器,這也需要更多的CPU和內存。另外采用了中間件也會帶來一個比較大的資源投入。
-
增加了網絡通信開銷
分布式系統的產生的網絡開銷比單機應用多很多,不能簡單把內部調用簡單改為分布式調用,吃虧很大。微服務架構下,獨立運行的組件都需要通過網絡進行互相通信。這樣系統需要有更加可靠和快速的網絡連接。
-
網絡安全
通過網絡進行通信的系統更容易產生安全缺陷。
-
測試難度
測試微服務架構的應用絕對比單體應用難很多,深有體會,集成測試過程是一場噩夢。
-
產品監控
監控微服務架構應用的成本會更高,很難獲得合適的工具,自研的成本也很高。
-
其它:另外例如方案設計,研發管理,問題排查確實都有不少挑戰。
微服務好處是很多,但缺點也很多,每個階段都需要我們去解決新架構帶來的新問題。微服務的系統復雜度、技術難度、人員成本、服務器成本都非常高。技術服務於業務,能簡單就簡單,這也是架構演化歷程的意義所在。在此附上相對簡單的微服務物理架構圖:
在上個階段的基礎上加入了服務注冊與發現和任務調度集群。
本階段為微服務階段,物理架構圖也是相對簡單的,完善的微服務架構體系還有着很多技術需要引入,比如:多因子統一認證登錄,配置中心,分布式鎖,分布式事務,分布式冪等性,服務監控預警,鏈路追蹤,服務自愈,日志分析,提煉代碼腳手架,服務自動化部署,無感部署雙AZ切換等等,在此附上微服務系統架構圖:
11總結
演化到此基本上大多數的技術問題都得以解決。但演化並未結束,隨着自身的不斷發展,可以開放服務接口對接第三方系統(如微信/支付寶第三方支付)。當微服務發展到非常龐大的微服務群體時進階到服務網格等等,個人水平有限繼續進化會到什么程度就不清楚了,但始終圍繞着高內聚低耦合、高可用、高性能、易擴展,易伸縮和安全性去進化架構。
目前上雲已成熱門詞語,各種技術方案也非常成熟,許多網站已經不需要再經歷大型網站所經歷過的架構演化之路。建立在雲平台所需要的一切技術資源,都可以按需購買,線性伸縮,不需要自己一點點地拼湊各種資源,綜合使用各種技術方案逐步完善自己的網站架構。
不要企圖通過技術來解決所有業務問題,而是根據業務具體分析,使用不同的技術架構、不同的業務處理模式來解決業務問題。
但也正因為這樣,網站架構技術演化過程也很難重現,以致於出現了很多為了使用技術而使用技術,而不是為了業務,本以為這樣搭建起來的網站就很高大上,其實都是徒勞。所以網站架構師更應該對這個過程深刻了解,在技術選型和架構決策時才能有的放矢,直擊要害。
主要參考文獻:(PDF也為您安排好了)
《大型網站技術架構:核心原理與案例分析》--獲取碼:135804
《系統架構》--獲取碼:135802
《微服務設計》--獲取碼:135806
演化架構圖原圖路徑:https://www.processon.com/view/6138293d63768906a2285e9e
微服務架構圖原圖路徑:https://www.processon.com/view/61399bb0e401fd1fb6b5a651
來源於微信公眾號:Java全棧布道師