分布式架構(gòu)淺談

引言
隨著越來(lái)越多的人參與到互聯(lián)網(wǎng)的浪潮來(lái),曾經(jīng)的單體應(yīng)用架構(gòu)越來(lái)越無(wú)法滿(mǎn)足需求,所以,分布式集群架構(gòu)出現(xiàn),也因此,分布式搭建開(kāi)發(fā)成為了Web開(kāi)發(fā)者必掌握的技能之一。那什么是分布式呢?怎么實(shí)現(xiàn)分布式以及怎么處理分布式帶來(lái)的問(wèn)題呢?本系列文章就來(lái)源于對(duì)分布式各組件系統(tǒng)的學(xué)習(xí)總結(jié),包含但不限于Zookeeper、Dubbo、消息隊(duì)列(ActiveMQ、Kafka、RabbitMQ)、Nosql(Redis、MongoDB)、Niginx、分庫(kù)分表MyCat、Netty等內(nèi)容。作為跟大多數(shù)人一樣的學(xué)習(xí)使用者,而非布道者,個(gè)人理解難免會(huì)有偏差或是其它錯(cuò)誤,希望各位讀者不吝指教。
正文
一、什么是分布式
簡(jiǎn)單的說(shuō),“分工協(xié)作,專(zhuān)人做專(zhuān)事”就是分布式的概念。就好比你是你們公司唯一的碼農(nóng),那么前后端都需要你自己來(lái)開(kāi)發(fā)(單體架構(gòu)),但隨著業(yè)務(wù)的增長(zhǎng),你確實(shí)忙不過(guò)來(lái)了,老板給你招來(lái)了一個(gè)前端,那么你就只需要專(zhuān)注后端開(kāi)發(fā)就行了(分布式)。但是軟件的分布式搭建遠(yuǎn)遠(yuǎn)不像現(xiàn)實(shí)例子中這么簡(jiǎn)單,需要考慮和處理很多方面的問(wèn)題,我們先了解以下幾個(gè)常見(jiàn)的概念:
集群:你們公司業(yè)務(wù)增長(zhǎng)的非常快,老板發(fā)現(xiàn)你一個(gè)后端忙不過(guò)來(lái)了,就又招了幾個(gè)后端開(kāi)發(fā)來(lái)協(xié)助你,這就是后端集群;再往后,發(fā)現(xiàn)前端也忙不過(guò)來(lái)了,又配備幾個(gè)前端,就是前端集群。所以也不難看出,將應(yīng)用拆分后,你可以有針對(duì)性地?cái)U(kuò)展單個(gè)服務(wù),做成集群,這就是分布式的好處之一。
節(jié)點(diǎn):這個(gè)也非常好理解,一個(gè)服務(wù)就是一個(gè)節(jié)點(diǎn),比如你就是后端集群中的一個(gè)節(jié)點(diǎn),而集群本身也可以看成是整個(gè)應(yīng)用的一個(gè)集群節(jié)點(diǎn)。
副本:副本就是為服務(wù)和數(shù)據(jù)提供的冗余,保證高可用。
中間件:為開(kāi)發(fā)者提供便利,屏蔽復(fù)雜的底層的一類(lèi)框架組件。如服務(wù)管理通信、序列化、負(fù)載均衡等組件。

上圖就是一個(gè)簡(jiǎn)單的分布式架構(gòu),但并不是所有的應(yīng)用一開(kāi)始就要設(shè)計(jì)為分布式架構(gòu),因?yàn)橐婚_(kāi)始業(yè)務(wù)量并不大,沒(méi)有必要耗費(fèi)大量的時(shí)間和成本去完成一個(gè)分布式架構(gòu),甚至有可能到最后都用不上,因此在設(shè)計(jì)時(shí)我們應(yīng)該遵循演進(jìn)原則,由簡(jiǎn)入深。下面就來(lái)簡(jiǎn)單分析一下分布式架構(gòu)的演進(jìn)過(guò)程。
二、分布式架構(gòu)的演化過(guò)程
單機(jī)版
以商城為例,為了簡(jiǎn)單說(shuō)明,這里就只列出用戶(hù)、訂單、配送服務(wù)。

如圖,大部分應(yīng)用最開(kāi)始都是將應(yīng)用和數(shù)據(jù)庫(kù)放到一臺(tái)物理機(jī)上提供服務(wù),但隨著訪(fǎng)問(wèn)量的提升,服務(wù)器負(fù)載越來(lái)越高,我們首先會(huì)優(yōu)化代碼、對(duì)機(jī)器做垂直擴(kuò)容(內(nèi)存、容量)等,但單臺(tái)機(jī)器的性能是存在上限的,且對(duì)單機(jī)擴(kuò)容的性?xún)r(jià)比會(huì)隨著性能的提升越來(lái)越低,那我們就會(huì)想到增加服務(wù)器。
將應(yīng)用服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器分離
在一開(kāi)始,我們可能只會(huì)增加一臺(tái)服務(wù)器,并將應(yīng)用和數(shù)據(jù)庫(kù)分離:

搭建應(yīng)用服務(wù)器集群
隨著訪(fǎng)問(wèn)量的繼續(xù)增加,單臺(tái)應(yīng)用服務(wù)器也無(wú)法滿(mǎn)足需求了,我們就需要搭建應(yīng)用服務(wù)器集群來(lái)對(duì)外提供服務(wù)了

但是,在搭建應(yīng)用服務(wù)器集群之后,問(wèn)題就出現(xiàn)了,用戶(hù)在訪(fǎng)問(wèn)時(shí),應(yīng)該到哪個(gè)服務(wù)器上去?如何平均服務(wù)器壓力?以及用戶(hù)的session如何維護(hù)(A首先訪(fǎng)問(wèn)了1號(hào)應(yīng)用服務(wù)器并登陸,但下次請(qǐng)求可能是去到2號(hào)服務(wù)器,但這臺(tái)服務(wù)器上并沒(méi)有用戶(hù)的session信息)?
我們可以在用戶(hù)層和應(yīng)用層之間加上一個(gè)負(fù)載均衡器來(lái)平衡服務(wù)器的負(fù)載,session可以采取同步的方式,或者增加單獨(dú)的session共享服務(wù)器。
數(shù)據(jù)庫(kù)讀寫(xiě)分離
應(yīng)用層的問(wèn)題暫時(shí)解決了,但是此時(shí)數(shù)據(jù)庫(kù)又頂不住了。那該如何做呢?只是簡(jiǎn)單的增加數(shù)據(jù)庫(kù)的服務(wù)器拉提供存儲(chǔ)和訪(fǎng)問(wèn)能力么?那肯定不行,這樣數(shù)據(jù)就不一致了。所以我們需要將數(shù)據(jù)庫(kù)分為讀庫(kù)和寫(xiě)庫(kù)。查詢(xún)請(qǐng)求都到讀庫(kù)去,而寫(xiě)入請(qǐng)求都到寫(xiě)庫(kù)去。

但這樣也存在幾個(gè)問(wèn)題:
數(shù)據(jù)如何同步以及同步延遲如何處理?
應(yīng)用層數(shù)據(jù)源的選擇
大數(shù)據(jù)查詢(xún)搜索,可以引入搜索引擎
避免每次訪(fǎng)問(wèn)直接到達(dá)數(shù)據(jù)庫(kù),可以引入redis等緩存數(shù)據(jù)庫(kù)緩存熱點(diǎn)數(shù)據(jù)
問(wèn)題看似都解決了,但是每個(gè)數(shù)據(jù)庫(kù)都存儲(chǔ)的是同樣的數(shù)據(jù),隨著業(yè)務(wù)繼續(xù)擴(kuò)大, 我們就不得不考慮對(duì)數(shù)據(jù)庫(kù)做水平或垂直拆分:
水平拆分:將同一個(gè)表中的數(shù)據(jù)拆分至多個(gè)數(shù)據(jù)庫(kù)中
垂直拆分:將不同業(yè)務(wù)的數(shù)據(jù)放到不同的數(shù)據(jù)庫(kù)中

應(yīng)用拆分
業(yè)務(wù)繼續(xù)增長(zhǎng),數(shù)據(jù)庫(kù)達(dá)到瓶頸時(shí)可以繼續(xù)增加服務(wù)器解決,但是應(yīng)用層呢?也只是單純的增加服務(wù)器么?基于二八原則,其實(shí)大部分訪(fǎng)問(wèn)量是集中在20%的功能上的,如果我們只是單純的增加服務(wù)器,那么無(wú)疑會(huì)浪費(fèi)掉許多的資源,所以我么會(huì)想到能不能針對(duì)這20%的應(yīng)用做擴(kuò)展呢?當(dāng)然是可以的,只不過(guò)我們需要先將應(yīng)用拆分為多個(gè)子系統(tǒng)(一般是根據(jù)業(yè)務(wù)):

隨著應(yīng)用拆分隨之而來(lái)的問(wèn)題是,公用的代碼如何處理?各服務(wù)之間如何通信?公用代碼我們不可能放到每個(gè)服務(wù)中去,而是應(yīng)該提出來(lái)對(duì)外提供服務(wù),同時(shí)服務(wù)之間的調(diào)用可以通過(guò)RPC或者HTTP方式來(lái)實(shí)現(xiàn)。
演化至此,這樣的架構(gòu)就是一個(gè)成熟的分布式架構(gòu)了,但是,架構(gòu)還是會(huì)隨著業(yè)務(wù)和技術(shù)的提升不停地演化;而此時(shí)你有沒(méi)有發(fā)現(xiàn)這樣的一個(gè)架構(gòu)和馮諾伊曼結(jié)構(gòu)很像呢!輸入輸出設(shè)備對(duì)應(yīng)用戶(hù)和服務(wù)之間的輸入輸出,數(shù)據(jù)庫(kù)服務(wù)器就像是存儲(chǔ)設(shè)備,而整個(gè)應(yīng)用層就像是一個(gè)CPU(控制器、運(yùn)算器)。所以,分布式架構(gòu)可以簡(jiǎn)單的理解為將多臺(tái)計(jì)算機(jī)組成的一臺(tái)超級(jí)計(jì)算機(jī)。
三、分布式架構(gòu)的設(shè)計(jì)
在設(shè)計(jì)分布式架構(gòu)時(shí),我們需要了解幾個(gè)基本的概念。
主流架構(gòu)模型-SOA和微服務(wù)
CAP和BASE理論
DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))
這些理論限于篇幅原因,這里就不展開(kāi)詳述,讀者可自行查閱。下面主要來(lái)談?wù)劮植际郊軜?gòu)的高可用設(shè)計(jì)。
分布式架構(gòu)的高可用設(shè)計(jì)
在分布式架構(gòu)中,常常面臨的兩個(gè)矛盾的問(wèn)題是一致性和高可用,這兩個(gè)是無(wú)法同時(shí)滿(mǎn)足的,那我們舍誰(shuí)取誰(shuí)呢?從用戶(hù)的角度分析,我們寧可獲取到舊數(shù)據(jù),也不愿意等半天都打不開(kāi)應(yīng)用,所以常常是保證高可用,讓數(shù)據(jù)達(dá)到最終一致性,那么如何設(shè)計(jì)高可用的分布式架構(gòu)呢?主要從以下幾個(gè)方面:
搭建服務(wù)集群,提高負(fù)載,避免單點(diǎn)故障。尤其是特別重要的服務(wù),如訪(fǎng)問(wèn)量較高的服務(wù)和核心服務(wù)(一旦掛掉就會(huì)導(dǎo)致整個(gè)應(yīng)用不可用的服務(wù))。
應(yīng)對(duì)災(zāi)難,搭建異地災(zāi)備,預(yù)防地區(qū)因發(fā)生地震、臺(tái)風(fēng)等自然災(zāi)害導(dǎo)致地區(qū)的集群服務(wù)器都不可用。
接口限流以及服務(wù)降級(jí)。為防止過(guò)高的并發(fā)量造成服務(wù)器負(fù)載過(guò)高而出現(xiàn)故障,應(yīng)對(duì)接口限流,同時(shí),當(dāng)某個(gè)或多個(gè)服務(wù)出現(xiàn)故障時(shí),應(yīng)當(dāng)服務(wù)降級(jí),避免拖累整個(gè)應(yīng)用。比如支付時(shí)因網(wǎng)絡(luò)故障等導(dǎo)致無(wú)法支付,但搜索商品和下單仍然可用。
故障監(jiān)控報(bào)警。
服務(wù)的可伸縮性,易于水平擴(kuò)張服務(wù)器數(shù)量。
使用緩存降低數(shù)據(jù)庫(kù)壓力。
使用CDN等加速靜態(tài)資源的訪(fǎng)問(wèn)。
高可用的分布式架構(gòu)需要考慮非常多的方面,針對(duì)不同的場(chǎng)景有不同的解決方案,而對(duì)于不同的公司而言也不需要一應(yīng)俱全,需要在實(shí)踐中多思考總結(jié),根據(jù)自己的業(yè)務(wù)情況來(lái)設(shè)計(jì)。
總結(jié)
本文從理論層面講述了分布式的基本概念、演化過(guò)程,以及設(shè)計(jì),從宏觀(guān)角度搞清楚分布式的起源以及分布式帶來(lái)的一系列問(wèn)題,也就能明白各項(xiàng)技術(shù)出現(xiàn)的原因以及應(yīng)用的場(chǎng)景。
原文鏈接:
https://blog.csdn.net/l6108003/article/details/94835586
