前言
在過(guò)去40 年里,軟件開(kāi)發(fā)的世界日新月異,微服務(wù)日趨流行。本文為我們揭示了微服務(wù)的五大關(guān)鍵好處,看它們是如何幫助我們提升軟件質(zhì)量并適應(yīng)新的業(yè)務(wù)需求。
彈性
維基百科將彈性定義為系統(tǒng)處理變化的能力。我對(duì)彈性的理解是在問(wèn)題被解決后系統(tǒng)從異常狀態(tài)(短暫的硬件故障以及意料之外的高網(wǎng)絡(luò)延遲等)或壓力期中優(yōu)雅恢復(fù),同時(shí)又不會(huì)影響系統(tǒng)性能的能力。
這雖然聽(tīng)上去很簡(jiǎn)單,但是在構(gòu)建面向微服務(wù)軟件的時(shí)候,問(wèn)題源會(huì)由于系統(tǒng)的分布式特性而被放大,有時(shí)很難(甚至不可能)防止所有的異常情況。
彈性是從錯(cuò)誤中優(yōu)雅恢復(fù)的能力。但它同樣也為系統(tǒng)帶來(lái)了新的復(fù)雜度:如果一個(gè)微服務(wù)出現(xiàn)了問(wèn)題,我們能否防止系統(tǒng)的常規(guī)故障?理想情況下,我們應(yīng)該以這樣一種方式來(lái)構(gòu)建服務(wù):僅對(duì)服務(wù)響應(yīng)進(jìn)行降級(jí)而非讓系統(tǒng)出現(xiàn)常規(guī)故障,即使這樣做也并不容易。
如今,各大公司的一個(gè)通病是系統(tǒng)存在可伸縮性問(wèn)題。如果你之前曾與某個(gè)單塊軟件打過(guò)交道,我確信你在伴隨公司的成長(zhǎng)過(guò)程中,必定會(huì)在某些時(shí)刻遭遇到容量問(wèn)題。
通常,這些問(wèn)題并不涉及應(yīng)用的每一層次或所有子系統(tǒng)。往往只有個(gè)別子系統(tǒng)或服務(wù)會(huì)明顯慢于其余部分,一旦沒(méi)有處理好容量問(wèn)題就會(huì)導(dǎo)致整個(gè)應(yīng)用發(fā)生故障。下圖描述了我們是如何對(duì)微服務(wù)進(jìn)行擴(kuò)展(擴(kuò)展成兩個(gè)郵件服務(wù))的,同時(shí)又不牽扯系統(tǒng)的其余部分:
讓我們來(lái)看一個(gè)關(guān)于車險(xiǎn)的場(chǎng)景,用于計(jì)算指定風(fēng)險(xiǎn)因素列表報(bào)價(jià)的服務(wù)便是該類問(wèn)題的一個(gè)例子。通過(guò)擴(kuò)展整個(gè)應(yīng)用來(lái)滿足對(duì)某個(gè)特定部分的需求是否有意義?如果你腦海中的答案是“否”,那么你離擁抱微服務(wù)更近了一步。微服務(wù)可以讓你僅僅按需擴(kuò)展系統(tǒng)的一部分,從而只加大系統(tǒng)特定部分的處理能力。讓我們來(lái)看一個(gè)關(guān)于車險(xiǎn)的場(chǎng)景,用于計(jì)算指定風(fēng)險(xiǎn)因素列表報(bào)價(jià)的服務(wù)便是該類問(wèn)題的一個(gè)例子。通過(guò)擴(kuò)展整個(gè)應(yīng)用來(lái)滿足對(duì)某個(gè)特定部分的需求是否有意義?如果你腦海中的答案是“否”,那么你離擁抱微服務(wù)更近了一步。微服務(wù)可以讓你僅僅按需擴(kuò)展系統(tǒng)的一部分,從而只加大系統(tǒng)特定部分的處理能力。
如果該保險(xiǎn)系統(tǒng)是一個(gè)面向微服務(wù)的系統(tǒng),那么我們只需要?jiǎng)?chuàng)建更多的微服務(wù)實(shí)例來(lái)負(fù)責(zé)計(jì)算就能解決報(bào)價(jià)計(jì)算需求過(guò)旺的問(wèn)題。請(qǐng)記住,擴(kuò)展服務(wù)會(huì)給運(yùn)維團(tuán)隊(duì)增加開(kāi)銷。
技術(shù)多樣性
軟件的世界每幾個(gè)月就會(huì)更新?lián)Q代。新語(yǔ)言進(jìn)入業(yè)界成為某類系統(tǒng)事實(shí)標(biāo)準(zhǔn)的節(jié)奏片刻未停。幾年前, Ruby onRails面世并在 2013年成為在各種新項(xiàng)目中使用昀多的 Web框架。Golang(由 Google創(chuàng)建的一門語(yǔ)言)因其結(jié)合了強(qiáng)大的性能與優(yōu)雅簡(jiǎn)潔的語(yǔ)法而成為當(dāng)前的一種趨勢(shì),任何只要擁有一門編程語(yǔ)言經(jīng)驗(yàn)的人都可以在幾天內(nèi)學(xué)會(huì)它。
在過(guò)去,我也曾使用 Python和 Java成功編寫過(guò)微服務(wù)。
尤其是 Java,自從 Spring Boot發(fā)布之后,它成為在編寫敏捷微服務(wù)方面相當(dāng)有吸引力的技術(shù)棧。
Django是一款強(qiáng)大且可用于編寫微服務(wù)的 Python框架,與 Ruby on Rails非常相似。通過(guò)它我們可以自動(dòng)化地進(jìn)行數(shù)據(jù)庫(kù)遷移,并可以非常輕松地完成創(chuàng)建 CRUD(創(chuàng)建、讀取、更新及刪除)服務(wù)的工作。
Node.js利用了著名語(yǔ)言 JavaScript的優(yōu)勢(shì),創(chuàng)建了一個(gè)新的服務(wù)端技術(shù)棧,從而改變了工程師們編寫新軟件的方式。
那么,將這些技術(shù)都結(jié)合起來(lái)會(huì)有什么問(wèn)題嗎?平心而論,這是一個(gè)優(yōu)勢(shì):我們可以選擇合適的工具來(lái)做相對(duì)應(yīng)的工作。
只要待集成的技術(shù)是標(biāo)準(zhǔn)化的,面向微服務(wù)的架構(gòu)便可以幫你實(shí)現(xiàn)這一點(diǎn)。正如我們?cè)谏衔闹幸呀?jīng)了解到的,一個(gè)微服務(wù)是非常小的,并且是一個(gè)自主運(yùn)維的軟件中的獨(dú)立部分。
下圖展示了微服務(wù)是如何隱藏?cái)?shù)據(jù)的存取邏輯的,兩個(gè)服務(wù)在存取數(shù)據(jù)方面共用同一個(gè)通信點(diǎn),從而能很好地互相解耦(一個(gè)服務(wù)實(shí)現(xiàn)發(fā)生變化時(shí)并不涉及任何其他服務(wù)):
此前我們?cè)懻摰叫阅艿膯?wèn)題。通常,系統(tǒng)的某些部分會(huì)比其他部分承受更多的壓力。通過(guò)利用當(dāng)代的多核 CPU進(jìn)行并行(并發(fā))編程可以解決其中的一些性能問(wèn)題。然而, Node.js并不是一門適合執(zhí)行并行任務(wù)的語(yǔ)言。針對(duì)那些處于壓力之下的微服務(wù)來(lái)說(shuō),我們可以選擇一門更加適合的語(yǔ)言來(lái)進(jìn)行開(kāi)發(fā),比如 Erlang,從而可以以一種更加優(yōu)雅的方式來(lái)管理并發(fā)。這樣做,花不了你兩周的時(shí)間。
在同一系統(tǒng)中使用多種技術(shù)存在著一個(gè)問(wèn)題:開(kāi)發(fā)人員和系統(tǒng)管理員需要知道所有的(或一部分)相關(guān)技能。擁抱微服務(wù)的公司通常可以秉持一門核心技術(shù)(在本書(shū)中,我們將會(huì)使用 Node.js),并輔以一些其他技術(shù)(我們除了使用 Docker來(lái)管理部署之外,還可以采用 Capistrano或 Fabricator來(lái)管理發(fā)布)。
可替換性
可替換性是指替換系統(tǒng)中某個(gè)組件而不影響系統(tǒng)行為的一種能力。當(dāng)我們?cè)谟懻撥浖臅r(shí)候,可替換性往往是與低耦合密不可分的。在編寫微服務(wù)的時(shí)候不能將內(nèi)部邏輯暴露給調(diào)用服務(wù),服務(wù)實(shí)現(xiàn)對(duì)客戶端來(lái)說(shuō)是透明的,客戶端了解的只有接口。讓我們來(lái)看看下面的例子,該接口是用 Java編寫的,僅需通過(guò)觀察接口就能識(shí)別出它存在著什么問(wèn)題。
public interface GeoIpService {
/**
*檢查IP是否屬于指定ISO代碼所對(duì)應(yīng)的國(guó)家
**/
boolean isIn(String ip, String isoCode) throws
SOAPFaultException;
}
初看該接口可以發(fā)現(xiàn)它是自描述的。它將檢查特定 IP是否屬于特定的國(guó)家,一旦服務(wù)出現(xiàn)重大問(wèn)題會(huì)拋出 SOAPFaultException。
如果我們構(gòu)建客戶端來(lái)消費(fèi)該接口,需要考慮到服務(wù)的上述邏輯,捕獲并處理 SoapFaultException。這等同于將服務(wù)內(nèi)部實(shí)現(xiàn)的細(xì)節(jié)暴露給了外部世界,從而很難再替換掉 GeoIpService接口。同樣的,事實(shí)上我們創(chuàng)建的某個(gè)服務(wù)如果關(guān)聯(lián)了應(yīng)用邏輯的某個(gè)部分則表明創(chuàng)建了一個(gè)限界上下文:即一個(gè)高內(nèi)聚的服務(wù)或服務(wù)集(通過(guò)集合所轄服務(wù)的協(xié)同工作可以達(dá)成一個(gè)目標(biāo))。
獨(dú)立性
不管我們?cè)趺磁Γ祟惖拇竽X都不擅長(zhǎng)解決復(fù)雜問(wèn)題。人類大腦昀有效的運(yùn)作模式是同一時(shí)間只做一件事情,所以我們可以將復(fù)雜問(wèn)題拆解成更小的問(wèn)題。面向微服務(wù)的架構(gòu)應(yīng)該也遵從這一方式:所有服務(wù)應(yīng)該都是獨(dú)立的,它們通過(guò)接口進(jìn)行交互。除了協(xié)定確認(rèn)接口這一環(huán)節(jié)之外,不同的工程師團(tuán)隊(duì)可以在無(wú)須交流的情況下完成對(duì)服務(wù)的開(kāi)發(fā)。一家采用了微服務(wù)的公司可以根據(jù)業(yè)務(wù)的需求來(lái)調(diào)整工程師團(tuán)隊(duì)的規(guī)模,從而能敏捷地響應(yīng)業(yè)務(wù)的高峰期或靜默期。
為什么可替換性如此重要
在前面的一個(gè)小節(jié)中,我們討論了該如何確定微服務(wù)的合理規(guī)模。按照普遍的經(jīng)驗(yàn)而言,一個(gè)團(tuán)隊(duì)?wèi)?yīng)該能在一個(gè) sprint內(nèi)完成一個(gè)微服務(wù)的重寫和部署。這樣做的背后的根本原因就是技術(shù)債務(wù)。
我會(huì)將技術(shù)債務(wù)定義為在一個(gè)既定計(jì)劃的周期內(nèi),初始技術(shù)設(shè)計(jì)與預(yù)期交付功能之間的偏差。某些方面的犧牲或錯(cuò)誤假設(shè)會(huì)導(dǎo)致編寫的軟件非常糟糕,這樣的軟件需要全盤重構(gòu)或重寫。在前面的例子中,接口在暴露給外部世界時(shí)明確表明必須使用 SOAP來(lái)調(diào)用 Web服務(wù)。一旦需要將客戶端代碼改造成 REST客戶端,REST客戶端根本無(wú)法處理 SOAP異常。
易于部署
微服務(wù)應(yīng)當(dāng)易于部署。作為軟件開(kāi)發(fā)者,我們知道在軟件的部署過(guò)程中很多事情都可能會(huì)出現(xiàn)問(wèn)題。正如前面所提到的,微服務(wù)是非常易于部署的,原因如下:
?少量的業(yè)務(wù)邏輯(從經(jīng)驗(yàn)上來(lái)說(shuō)是只需兩周即可完成從無(wú)到有的編寫)導(dǎo)致更易于部署。
?微服務(wù)是自治的工作單元,所以升級(jí)一個(gè)服務(wù)對(duì)于復(fù)雜系統(tǒng)來(lái)說(shuō)是一個(gè)局部可控的問(wèn)題。無(wú)須重新部署整個(gè)系統(tǒng)。
?微服務(wù)架構(gòu)中的基礎(chǔ)設(shè)施和配置應(yīng)該盡可能自動(dòng)化。在本書(shū)的后續(xù)部分中,我們將學(xué)習(xí)如何使用 Docker來(lái)部署微服務(wù),以及這樣做相比于傳統(tǒng)部署技術(shù)會(huì)有怎樣的優(yōu)勢(shì)。
-
微服務(wù)
+關(guān)注
關(guān)注
0文章
145瀏覽量
7742
發(fā)布評(píng)論請(qǐng)先 登錄
華為汪濤提出解鎖5G-A潛能的五大關(guān)鍵方向
工業(yè)化超聲波清洗設(shè)備的五大關(guān)鍵特性

不只依賴光刻機(jī)!芯片制造的五大工藝大起底!

NVIDIA 發(fā)布保障代理式 AI 應(yīng)用安全的 NIM 微服務(wù)
微服務(wù)容器化部署好處多嗎?
德州儀器分析服務(wù)器電源設(shè)計(jì)中的五大趨勢(shì)

解析愛(ài)普生RTC芯片選型的五大關(guān)鍵

工業(yè)網(wǎng)絡(luò)管理新紀(jì)元:揭秘五大“利器”,化繁為簡(jiǎn)的智慧轉(zhuǎn)型

寶藏級(jí)微服務(wù)架構(gòu)工具合集
Skydel 24.9版本震撼發(fā)布,升級(jí)五大關(guān)鍵功能

微服務(wù)架構(gòu)與容器云的關(guān)系與區(qū)別
入門級(jí)攻略:如何容器化部署微服務(wù)?
揭秘高質(zhì)量點(diǎn)焊機(jī)的五大標(biāo)準(zhǔn):打造焊接性能的基石

評(píng)論