一、分布式系統(tǒng)為什么具有健壯性
健壯性是指在異常和危險(xiǎn)情況下系統(tǒng)生存的能力,分布式系統(tǒng)一般具有健壯性,這是因?yàn)椋?/p>
1、分布式系統(tǒng)的處理和控制功能是分布的,任何站點(diǎn)發(fā)生的故障都不會(huì)給整個(gè)系統(tǒng)造成太大的影響。
2、當(dāng)分布式系統(tǒng)中的設(shè)備出現(xiàn)故障時(shí),可以通過(guò)容錯(cuò)技術(shù)實(shí)現(xiàn)系統(tǒng)的重構(gòu),以保證系統(tǒng)的正常運(yùn)行。

二、怎么構(gòu)建健壯的分布式系統(tǒng)
分布式系統(tǒng)一般都具有健壯性,不過(guò)面對(duì)越來(lái)越普遍隨機(jī)故障,如果系統(tǒng)構(gòu)建不當(dāng)?shù)脑?,也?huì)導(dǎo)致系統(tǒng)運(yùn)行出現(xiàn)問(wèn)題,要構(gòu)建健壯的分布式系統(tǒng),主要注意以下幾點(diǎn):
1、最小化組件間依賴
分布式系統(tǒng)的組件相互通信以獲取數(shù)據(jù)或功能。在這兩種情況下,我們都可以通過(guò)將數(shù)據(jù)/功能推送到調(diào)用組件而不是遠(yuǎn)程訪問(wèn)來(lái)減少連接需求。
構(gòu)建大規(guī)模分布式系統(tǒng)迫使我們放棄標(biāo)準(zhǔn)軟件工程的許多“最佳實(shí)踐”。要記住的關(guān)鍵是,當(dāng)我們采用分布式系統(tǒng)的復(fù)雜性來(lái)實(shí)現(xiàn)可擴(kuò)展性時(shí),我們還需要盡可能地控制“分布”。
(1)重復(fù)數(shù)據(jù)
如果我們經(jīng)常從另一個(gè)組件訪問(wèn)一些數(shù)據(jù),我們可以在我們的組件中復(fù)制它,而不必在運(yùn)行時(shí)檢索它。這可以大大減少運(yùn)行時(shí)依賴并幫助改善我們組件的延遲。
經(jīng)常訪問(wèn)但有一定規(guī)律性變化的數(shù)據(jù)可以通過(guò)定期緩存刷新來(lái)臨時(shí)緩存。更改頻率更低或從不更改的數(shù)據(jù)(例如客戶姓名)可以直接存儲(chǔ)在我們的組件中。如果/當(dāng)這些數(shù)據(jù)發(fā)生變化時(shí),我們可能需要做一些額外的工作,但是這種增加的小開(kāi)銷通常是值得的,因?yàn)樗梢蕴岣邚椥浴?/p>
(2)非規(guī)范化數(shù)據(jù)
非規(guī)范化是在組件內(nèi)發(fā)生的一種特殊形式的重復(fù)。如果我們使用關(guān)系數(shù)據(jù)存儲(chǔ),我們可以通過(guò)在主實(shí)體中復(fù)制數(shù)據(jù)來(lái)降低查看多個(gè)實(shí)體的成本。本地化分散數(shù)據(jù)以獲得更好性能的原則也適用于此。
(3)庫(kù)
為了減輕另一個(gè)組件的功能依賴性,我們可以將遠(yuǎn)程組件打包為庫(kù)并將其嵌入到我們的組件中。這并不總是可能的(它可能是用其他語(yǔ)言編寫(xiě)的,或者太大而不能成為一個(gè)庫(kù))并且會(huì)帶來(lái)一系列問(wèn)題(功能的變化需要跨多個(gè)組件進(jìn)行庫(kù)升級(jí)),但是如果功能很關(guān)鍵并且經(jīng)常被大規(guī)模訪問(wèn),這是打破組件間連接并使其成為本地的可行方法。
2、隔離錯(cuò)誤
錯(cuò)誤隔離很重要,原因有兩個(gè)。一是個(gè)別錯(cuò)誤在分布式系統(tǒng)中更常見(jiàn)(許多移動(dòng)部件的簡(jiǎn)單功能)。另一個(gè)是,如果我們不能防止整個(gè)系統(tǒng)中的聯(lián)鎖錯(cuò)誤,那么我們首先就失去了構(gòu)建復(fù)雜體的理由。
錯(cuò)誤隔離的主要結(jié)構(gòu)是SLA。每個(gè)組件都聲明了一些質(zhì)量參數(shù),它將在執(zhí)行功能時(shí)得到尊重。這些參數(shù)可以包括延遲、錯(cuò)誤率、并發(fā)性等。在此SLA之外,調(diào)用它的組件會(huì)假定它已失敗并需要自行采取適當(dāng)?shù)拇胧?。如果組件本身檢測(cè)到它無(wú)法維護(hù)其SLA,它可以先發(fā)制人地告訴其調(diào)用者暫停并稍后再來(lái)調(diào)用。為了保持整體系統(tǒng)健康,最好是快速失敗而不是在違反SLA的情況下成功。兩個(gè)組件(一個(gè)被喚起的和一個(gè)喚起的)都必須為此設(shè)置機(jī)制。
(1)保護(hù)調(diào)用者
A、超時(shí):如果被調(diào)用的組件在其SLA內(nèi)沒(méi)有響應(yīng),調(diào)用者必須超時(shí)(放棄)并改用一些回退機(jī)制(即使它拋出錯(cuò)誤)來(lái)維護(hù)自己的SLA并防止一連串的SLA違規(guī)。
B、重試:由于網(wǎng)絡(luò)不可靠,分布式系統(tǒng)中的許多錯(cuò)誤只是隨機(jī)的。如果調(diào)用者自己的SLA允許,調(diào)用者可以重試該操作。重試的前提是操作的冪等性。即它不應(yīng)該改變狀態(tài)或只做一次,即使它被調(diào)用了兩次。
C、斷路器:如果對(duì)組件的調(diào)用連續(xù)失敗,調(diào)用者可以通過(guò)“打開(kāi)電路”切斷連接并停止調(diào)用一段時(shí)間。由于調(diào)用者已經(jīng)有一些錯(cuò)誤場(chǎng)景的備份行為,這節(jié)省了調(diào)用者寶貴的資源,這些資源本來(lái)會(huì)被浪費(fèi)掉。停止調(diào)用還可以減少被調(diào)用組件的負(fù)載,并給它一些恢復(fù)的喘息空間。
(2)保護(hù)被調(diào)用
A、隨機(jī)間隔:雖然重試可以減少錯(cuò)誤,但在一個(gè)頻繁使用的組件中出現(xiàn)一個(gè)小的性能問(wèn)題可能會(huì)導(dǎo)致其所有調(diào)用者一次重試。這種“重試風(fēng)暴”會(huì)造成負(fù)載峰值并阻止該組件恢復(fù)。為了防止這種情況,重試應(yīng)該在它們之間有一個(gè)隨機(jī)的時(shí)間間隔,以便交錯(cuò)加載。
B、背壓:如果一個(gè)組件檢測(cè)到自己承受過(guò)多的負(fù)載并且即將違反其SLA,它可以搶先開(kāi)始丟棄新請(qǐng)求,直到其性能得到控制。這比接受它知道它不能在SLA內(nèi)提供服務(wù)或沒(méi)有完全崩潰風(fēng)險(xiǎn)的請(qǐng)求要好得多。
3、在系統(tǒng)中建立緩沖區(qū)
(1)異步通信
消息總線之類的異步通信通道允許調(diào)用遠(yuǎn)程組件,而無(wú)需非常嚴(yán)格的SLA依賴。通過(guò)讓被調(diào)用組件準(zhǔn)備好而不是立即使用消息,系統(tǒng)對(duì)增加的工作負(fù)載的需求變得更加靈活。
(2)彈性配置
可擴(kuò)展性最終歸結(jié)為充分利用可用硬件。但是,如果看到規(guī)模增長(zhǎng),讓系統(tǒng)緩口氣的一個(gè)簡(jiǎn)單方法是分配更多硬件。雖然這僅在我們能夠承受的成本范圍內(nèi)是可行的,但它為我們提供了抵御不可預(yù)測(cè)的負(fù)載變化的最后一道防線。