seo免費(fèi)網(wǎng)站建設(shè)用今日頭條導(dǎo)入自己網(wǎng)站外鏈
文章目錄
- 初始架構(gòu):單機(jī)架構(gòu)
- 第一次演進(jìn):Tomcat與數(shù)據(jù)庫分開部署
- 第二次演進(jìn):引入本地緩存和分布式緩存
- 第三次演進(jìn):引入反向代理實(shí)現(xiàn)負(fù)載均衡
- 第四次演進(jìn):數(shù)據(jù)庫讀寫分離
- 第五次演進(jìn):數(shù)據(jù)庫按業(yè)務(wù)分庫
- 第六次演進(jìn):把大表拆分為小表
- 第七次演進(jìn):使用LVS或F5來使多個(gè)Nginx負(fù)載均衡
- 第八次演進(jìn):通過DNS輪詢實(shí)現(xiàn)機(jī)房間的負(fù)載均衡
- 第九次演進(jìn):引入NoSQL數(shù)據(jù)庫和搜索引擎等技術(shù)
- 第十次演進(jìn):大應(yīng)用拆分為小應(yīng)用
- 第十一次演進(jìn):復(fù)用的功能抽離成微服務(wù)
好的架構(gòu)不是設(shè)計(jì)出來的,而是演進(jìn)出來的。
系統(tǒng)立項(xiàng)之初,就想著設(shè)計(jì)一個(gè)大而全的架構(gòu),期待著它能夠解決各個(gè)階段的各種問題,這是不可能的。因?yàn)樵诔跗诤茈y預(yù)估后期業(yè)務(wù)的變化,如果在初期就落地一個(gè)大而全的項(xiàng)目,那么人力成本和時(shí)間成本都會(huì)很高。同時(shí),架構(gòu)并不是千篇一律的,千萬不能在不同的業(yè)務(wù)和系統(tǒng)中生搬硬套同一個(gè)架構(gòu)。先快速落地,并關(guān)注業(yè)務(wù)的變化和系統(tǒng)的健壯程度,在不同階段對當(dāng)前架構(gòu)所面臨的問題進(jìn)行復(fù)盤和處理,選擇一個(gè)更適合自身的方向進(jìn)行優(yōu)化和改進(jìn),這才是常規(guī)的做法。
在每個(gè)階段,找到對應(yīng)該階段網(wǎng)站架構(gòu)所面臨的問題,在不斷解決這些問題的過程中,系統(tǒng)的架構(gòu)在不斷地朝著正確的方向演進(jìn)。
這里我們以淘寶為例,分析淘寶網(wǎng)站從一百個(gè)并發(fā)到億級并發(fā)情況下服務(wù)架構(gòu)的演進(jìn)過程。淘寶作為電商平臺,其架構(gòu)經(jīng)歷了多次演進(jìn),以支持其快速增長的業(yè)務(wù)和高并發(fā)的用戶請求。早期的淘寶采用了單體架構(gòu),隨著業(yè)務(wù)的發(fā)展,逐步演進(jìn)到使用分布式緩存、負(fù)載均衡、服務(wù)化等技術(shù),最終采用了微服務(wù)架構(gòu)。
初始架構(gòu):單機(jī)架構(gòu)
在淘寶網(wǎng)站最初時(shí),應(yīng)用數(shù)量與用戶數(shù)都較少,可以把Tomcat和數(shù)據(jù)庫部署在同一臺服務(wù)器上。
瀏覽器往www.taobao.com發(fā)起請求時(shí),首先經(jīng)過DNS服務(wù)器(域名系統(tǒng))把域名轉(zhuǎn)換為實(shí)際IP地址10.102.4.1,瀏覽器轉(zhuǎn)而訪問該IP對應(yīng)的Tomcat。
如下圖所示:
新的技術(shù)挑戰(zhàn): 隨著用戶數(shù)的增長,Tomcat和數(shù)據(jù)庫之間競爭資源,單機(jī)性能不足以支撐業(yè)務(wù),架構(gòu)演進(jìn)勢在必行。
第一次演進(jìn):Tomcat與數(shù)據(jù)庫分開部署
第一次演進(jìn)沒有什么特別的,將 Tomcat 和數(shù)據(jù)庫分別獨(dú)占服務(wù)器資源,顯著提高兩者各自性能。
如下圖所示:
新的技術(shù)挑戰(zhàn): 隨著用戶數(shù)的增長,并發(fā)讀寫數(shù)據(jù)庫成為瓶頸。
第二次演進(jìn):引入本地緩存和分布式緩存
第二次架構(gòu)演進(jìn)引入了緩存,在Tomcat服務(wù)器上增加本地緩存,并在外部增加分布式緩存,緩存熱門商品信息或熱門商品的html頁面等。
通過緩存能把絕大多數(shù)請求在讀寫數(shù)據(jù)庫前攔截掉,大大降低數(shù)據(jù)庫壓力。其中涉及的技術(shù)包括:使用memcached作為本地緩存,使用Redis作為分布式緩存,還會(huì)涉及緩存一致性、緩存穿透/擊穿、緩存雪崩、熱點(diǎn)數(shù)據(jù)集中失效等問題。
演進(jìn)之后,如下圖所示:
新的技術(shù)挑戰(zhàn):緩存抗住了大部分的訪問請求,隨著用戶數(shù)的增長,并發(fā)壓力主要落在單機(jī)的Tomcat上,響應(yīng)逐漸變慢
第三次演進(jìn):引入反向代理實(shí)現(xiàn)負(fù)載均衡
在多臺服務(wù)器上分別部署Tomcat,使用反向代理軟件(Nginx)把請求均勻分發(fā)到每個(gè)Tomcat中。此處假設(shè)Tomcat最多支持100個(gè)并發(fā),Nginx最多支持50000個(gè)并發(fā),那么理論上Nginx把請求分發(fā)到500個(gè)Tomcat上,就能抗住50000個(gè)并發(fā)。
其中涉及的技術(shù)包括:Nginx、HAProxy,兩者都是工作在網(wǎng)絡(luò)第七層的反向代理軟件,主要支持http協(xié)議,還會(huì)涉及session共享、文件上傳下載的問題。
一起來看看使用反向代理之后的架構(gòu)圖:
新的技術(shù)挑戰(zhàn): 反向代理使應(yīng)用服務(wù)器可支持的并發(fā)量大大增加,但并發(fā)量的增長也意味著更多請求穿透到數(shù)據(jù)庫,單機(jī)的數(shù)據(jù)庫最終成為瓶頸
第四次演進(jìn):數(shù)據(jù)庫讀寫分離
把數(shù)據(jù)庫劃分為讀庫和寫庫,讀庫可以有多個(gè),通過同步機(jī)制把寫庫的數(shù)據(jù)同步到讀庫。對于需要查詢最新寫入數(shù)據(jù)場景,可通過在緩存中多寫一份,通過緩存獲得最新數(shù)據(jù)。
其中涉及的技術(shù)包括:Mycat,它是數(shù)據(jù)庫中間件,可通過它來組織數(shù)據(jù)庫的分離讀寫和分庫分表,客戶端通過它來訪問下層數(shù)據(jù)庫,還會(huì)涉及數(shù)據(jù)同步,數(shù)據(jù)一致性的問題。
讀寫分離之后的架構(gòu)圖:
新的技術(shù)挑戰(zhàn): 業(yè)務(wù)逐漸變多,不同業(yè)務(wù)之間的訪問量差距較大,不同業(yè)務(wù)直接競爭數(shù)據(jù)庫,相互影響性能
第五次演進(jìn):數(shù)據(jù)庫按業(yè)務(wù)分庫
數(shù)據(jù)庫按業(yè)務(wù)分庫,把不同業(yè)務(wù)的數(shù)據(jù)保存到不同的數(shù)據(jù)庫中,使業(yè)務(wù)之間的資源競爭降低,對于訪問量大的業(yè)務(wù),可以部署更多的服務(wù)器來支撐。這樣同時(shí)會(huì)導(dǎo)致跨業(yè)務(wù)的表無法直接做關(guān)聯(lián)分析,需要通過其他途徑來解決。
分庫之后的架構(gòu)圖如下所示:
新的技術(shù)挑戰(zhàn): 隨著用戶數(shù)的增長,單機(jī)的寫庫會(huì)逐漸達(dá)到性能瓶頸
第六次演進(jìn):把大表拆分為小表
比如針對評論數(shù)據(jù),可按照商品ID進(jìn)行hash,路由到對應(yīng)的表中存儲(chǔ)。
針對支付記錄,可按照小時(shí)創(chuàng)建表,每個(gè)小時(shí)表繼續(xù)拆分為小表,使用用戶ID或記錄編號來路由數(shù)據(jù)。
只要實(shí)時(shí)操作的表數(shù)據(jù)量足夠小,請求能夠足夠均勻的分發(fā)到多臺服務(wù)器上的小表,那數(shù)據(jù)庫就能通過水平擴(kuò)展的方式來提高性能。其中前面提到的Mycat也支持在大表拆分為小表情況下的訪問控制。
這種做法顯著地增加了數(shù)據(jù)庫運(yùn)維的難度,對DBA的要求較高。數(shù)據(jù)庫設(shè)計(jì)到這種結(jié)構(gòu)時(shí),已經(jīng)可以稱為分布式數(shù)據(jù)庫。
我們來看拆分小表之后的架構(gòu)圖:
新的技術(shù)挑戰(zhàn): 數(shù)據(jù)庫和Tomcat都能夠水平擴(kuò)展,可支撐的并發(fā)大幅提高。然而隨著用戶數(shù)的增長,最終單機(jī)的Nginx會(huì)成為瓶頸
第七次演進(jìn):使用LVS或F5來使多個(gè)Nginx負(fù)載均衡
由于瓶頸在Nginx,因此無法通過兩層的Nginx來實(shí)現(xiàn)多個(gè)Nginx的負(fù)載均衡。LVS和F5是工作在網(wǎng)絡(luò)第四層的負(fù)載均衡解決方案,其中LVS是軟件,運(yùn)行在操作系統(tǒng)內(nèi)核態(tài),可對TCP請求或更高層級的網(wǎng)絡(luò)協(xié)議進(jìn)行轉(zhuǎn)發(fā),因此支持的協(xié)議更豐富,并且性能也遠(yuǎn)高于Nginx,可假設(shè)單機(jī)的LVS可支持幾十萬個(gè)并發(fā)的請求轉(zhuǎn)發(fā)。
F5是一種負(fù)載均衡硬件,與LVS提供的能力類似,性能比LVS更高,但價(jià)格昂貴。
由于LVS是單機(jī)版的軟件,若LVS所在服務(wù)器宕機(jī)則會(huì)導(dǎo)致整個(gè)后端系統(tǒng)都無法訪問,因此需要有備用節(jié)點(diǎn)。
架構(gòu)圖如下:
新的技術(shù)挑戰(zhàn):由于LVS也是單機(jī)的,隨著并發(fā)數(shù)增長到幾十萬時(shí),LVS服務(wù)器最終會(huì)達(dá)到瓶頸。此時(shí)用戶數(shù)達(dá)到千萬甚至上億級別,用戶分布在不同的地區(qū),與服務(wù)器機(jī)房距離不同,導(dǎo)致了訪問的延遲會(huì)明顯不同
第八次演進(jìn):通過DNS輪詢實(shí)現(xiàn)機(jī)房間的負(fù)載均衡
在DNS服務(wù)器中可配置一個(gè)域名對應(yīng)多個(gè)IP地址,每個(gè)IP地址對應(yīng)到不同的機(jī)房里的虛擬IP。
當(dāng)用戶訪問www.taobao.com時(shí),DNS服務(wù)器會(huì)使用輪詢策略或其他策略,來選擇某個(gè)IP供用戶訪問。此方式能實(shí)現(xiàn)機(jī)房間的負(fù)載均衡
至此,系統(tǒng)可做到機(jī)房級別的水平擴(kuò)展,千萬級到億級的并發(fā)量都可通過增加機(jī)房來解決,系統(tǒng)入口處的請求并發(fā)量不再是問題。
演進(jìn)之后的架構(gòu)圖如下:
新的技術(shù)挑戰(zhàn): 隨著數(shù)據(jù)的豐富程度和業(yè)務(wù)的發(fā)展,檢索、分析等需求越來越豐富,單單依靠數(shù)據(jù)庫無法解決如此豐富的需求
第九次演進(jìn):引入NoSQL數(shù)據(jù)庫和搜索引擎等技術(shù)
當(dāng)數(shù)據(jù)庫中的數(shù)據(jù)多到一定規(guī)模時(shí),數(shù)據(jù)庫就不適用于復(fù)雜的查詢了,往往只能滿足普通查詢的場景。
對于統(tǒng)計(jì)報(bào)表場景,在數(shù)據(jù)量大時(shí)不一定能跑出結(jié)果,而且在跑復(fù)雜查詢時(shí)會(huì)導(dǎo)致其他查詢變慢。
對于全文檢索、可變數(shù)據(jù)結(jié)構(gòu)等場景,數(shù)據(jù)庫天生不適用。因此需要針對特定的場景,引入合適的解決方案。
如對于海量文件存儲(chǔ),可通過分布式文件系統(tǒng)HDFS解決,對于key value類型的數(shù)據(jù),可通過Redis解決,對于全文檢索場景,可通過搜索引擎如ElasticSearch解決,對于多維分析場景,可通過Kylin或Druid等方案解決。
當(dāng)然,引入更多組件同時(shí)會(huì)提高系統(tǒng)的復(fù)雜度,不同的組件保存的數(shù)據(jù)需要同步,需要考慮一致性的問題,需要有更多的運(yùn)維手段來管理這些組件等。
引入NoSQL和搜索引擎的架構(gòu)圖:
新的技術(shù)挑戰(zhàn): 引入更多組件解決了豐富的需求,業(yè)務(wù)維度能夠極大擴(kuò)充,隨之而來的是一個(gè)應(yīng)用中包含了太多的業(yè)務(wù)代碼,業(yè)務(wù)的升級迭代變得困難。
第十次演進(jìn):大應(yīng)用拆分為小應(yīng)用
為了應(yīng)對日益復(fù)雜的業(yè)務(wù)場景,通過使用分而治之的手段將整個(gè)網(wǎng)站業(yè)務(wù)拆分成不同的產(chǎn)品線,通過分布式服務(wù)來協(xié)同工作。
按照業(yè)務(wù)板塊來劃分應(yīng)用代碼,使單個(gè)應(yīng)用的職責(zé)更清晰,相互之間可以做到獨(dú)立升級迭代。這時(shí)候應(yīng)用之間可能會(huì)涉及到一些公共配置,可以通過分布式配置中心Zookeeper來解決。
架構(gòu)圖如下:
新的技術(shù)挑戰(zhàn): 不同應(yīng)用之間存在共用的模塊,由應(yīng)用單獨(dú)管理會(huì)導(dǎo)致相同代碼存在多份,導(dǎo)致公共功能升級時(shí)全部應(yīng)用代碼都要跟著升級。
第十一次演進(jìn):復(fù)用的功能抽離成微服務(wù)
如用戶管理、訂單、支付、鑒權(quán)等功能在多個(gè)應(yīng)用中都存在,那么可以把這些功能的代碼單獨(dú)抽取出來形成一個(gè)單獨(dú)的服務(wù)來管理,這樣的服務(wù)就是所謂的微服務(wù)。應(yīng)用通過HTTP、TCP或RPC請求等多種方式來訪問服務(wù),每個(gè)單獨(dú)的服務(wù)都可以由單獨(dú)的團(tuán)隊(duì)來管理。
此外,可以通過Dubbo、SpringCloud等框架實(shí)現(xiàn)服務(wù)治理、限流、熔斷、降級等功能,提高服務(wù)的穩(wěn)定性和可用性。
微服務(wù)架構(gòu)并不是神話故事中的孫悟空,某一天忽然從石頭縫里蹦出來了。微服務(wù)架構(gòu)并不神秘,在“微服務(wù)架構(gòu)”這個(gè)概念“火”起來之前,微服務(wù)架構(gòu)叫什么?或者換一個(gè)說法:“微服務(wù)架構(gòu)的雛形是什么?”其實(shí),前文中網(wǎng)站架構(gòu)演進(jìn)的過程已經(jīng)給出了答案。在微服務(wù)架構(gòu)這個(gè)概念變得流行之前,技術(shù)架構(gòu)也在不斷優(yōu)化和演進(jìn)。
在微服務(wù)架構(gòu)這個(gè)概念“火”起來之前,人們會(huì)用“分布式服務(wù)”或“服務(wù)化”來概括這種將大系統(tǒng)拆分為小系統(tǒng)的架構(gòu)模式
,與微服務(wù)架構(gòu)的方式很像,也是對巨無霸的單體應(yīng)用進(jìn)行拆分,并結(jié)合RPC協(xié)議進(jìn)行服務(wù)通信和調(diào)用。常見技術(shù)有Dubbo、DubboX、CXF、gRPC、HSF、Motan等。隨著微服務(wù)概念的流行、微服務(wù)生態(tài)的完善和微服務(wù)架構(gòu)落地規(guī)則的細(xì)化,現(xiàn)在業(yè)內(nèi)人士都默認(rèn)將這種架構(gòu)方式稱為微服務(wù)架構(gòu)了。
有人肯定會(huì)有疑問,難道只能往微服務(wù)架構(gòu)的方向上演進(jìn)嗎?答案肯定不是,在前面的架構(gòu)演進(jìn)圖中,演進(jìn)方向是一條筆直的線。而現(xiàn)實(shí)情況中肯定是有不同分支的,系統(tǒng)架構(gòu)的演進(jìn)并不是一條筆直的線,根據(jù)業(yè)務(wù)大小和業(yè)務(wù)側(cè)重點(diǎn)的不同,系統(tǒng)架構(gòu)在演進(jìn)時(shí)也會(huì)朝著不同的方向發(fā)展,微服務(wù)架構(gòu)只是眾多技術(shù)架構(gòu)中的一個(gè),適合自身業(yè)務(wù)系統(tǒng)和技術(shù)團(tuán)隊(duì)的才是最好的架構(gòu)
。而且近些年又出現(xiàn)了Service Mesh、DDD領(lǐng)域驅(qū)動(dòng)、云原生等比較流行的技術(shù)方案,今后還會(huì)有更加優(yōu)秀的技術(shù)架構(gòu)和落地方案出現(xiàn)。