學(xué)習(xí)完整課程請移步 互聯(lián)網(wǎng) Java 全棧工程師
集中式與分布式
要談微服務(wù),那么必須建立在分布式的基礎(chǔ)上,對于一個集中式系統(tǒng)也無需談微服務(wù)。
集中式
集中式系統(tǒng)用一句話概括就是:一個主機帶多個終端。終端沒有數(shù)據(jù)處理能力前鹅,僅負(fù)責(zé)數(shù)據(jù)的錄入和輸出。而運算尺栖、存儲等全部在主機上進行嫡纠。
集中式系統(tǒng)的最大的特點就是部署結(jié)構(gòu)非常簡單,底層一般采用從IBM延赌、HP等廠商購買到的昂貴的大型主機除盏。因此無需考慮如何對服務(wù)進行多節(jié)點的部署,也就不用考慮各節(jié)點之間的分布式協(xié)作問題挫以。但是者蠕,由于采用單機部署。很可能帶來系統(tǒng)大而復(fù)雜掐松、難于維護踱侣、發(fā)生單點故障(單個點發(fā)生故障的時候會波及到整個系統(tǒng)或者網(wǎng)絡(luò),從而導(dǎo)致整個系統(tǒng)或者網(wǎng)絡(luò)的癱瘓)大磺、擴展性差等問題抡句。
分布式
分布式就是一群獨立計算機集合共同對外提供服務(wù),但是對于系統(tǒng)的用戶來說杠愧,就像是一臺計算機在提供服務(wù)一樣待榔。分布式意味著可以采用更多的普通計算機(相對于昂貴的大型機)組成分布式集群對外提供服務(wù)。計算機越多,CPU锐锣、內(nèi)存腌闯、存儲資源等也就越多,能夠處理的并發(fā)訪問量也就越大雕憔。
拿電商網(wǎng)站來說姿骏,我們一般把一個電商網(wǎng)站橫向拆分成商品模塊、訂單模塊斤彼、購物車模塊分瘦、消息模塊、支付模塊等畅卓。然后我們把不同的模塊部署到不同的機器上擅腰,各個模塊之間通過遠程服務(wù)調(diào)用(RPC
)等方式進行通信。以一個分布式的系統(tǒng)對外提供服務(wù)翁潘。
服務(wù)化
提到分布式,一個不得不提的詞就是服務(wù)化歼争,服務(wù)化架構(gòu)使搭建分布式系統(tǒng)成為了可能拜马。
傳統(tǒng)的軟件開發(fā)面臨著很多的問題,比如: 代碼重復(fù)率高沐绒、代碼龐大難以維護俩莽、無法快速迭代、測試成本高乔遮、可伸縮性差扮超、可靠性差、模塊間高度依賴蹋肮。為了解決上面這些問題出刷,我們一般采用拆分、解耦坯辩、分層馁龟、獨立等方式來解決。有了服務(wù)化架構(gòu)漆魔,我們就可以在很大程度上解決這些問題坷檩。
服務(wù)化是一種粗粒度、松耦合的以服務(wù)為中心的架構(gòu)改抡,服務(wù)之間通過定義明確的協(xié)議和接口進行通信矢炼。
這里說到的“服務(wù)”,本質(zhì)上來說阿纤,就是指“RPC”句灌。單純的RPC功能實現(xiàn),其實很簡單阵赠,無非就是client發(fā)起調(diào)用涯塔,中間某個組件(甚至就是client本身)攔截調(diào)用信息肌稻,序列化后將信息傳輸?shù)絪erver端,server端收到調(diào)用請求后反序列化匕荸,根據(jù)請求詳細(xì)發(fā)起實際調(diào)用后返回響應(yīng)傳輸回給client端爹谭。這樣的RPC很常見,比如常見的存儲過程調(diào)用就是一例榛搔。但是在一個復(fù)雜的業(yè)務(wù)環(huán)境诺凡,如何管理和協(xié)同這些大量的RPC才是最麻煩的事情。所以践惑,一般提到的“服務(wù)化”更多指的是對RPC的管理腹泌。服務(wù)化一般關(guān)注服務(wù)注冊,服務(wù)協(xié)調(diào)尔觉,服務(wù)可用性凉袱,服務(wù)通訊協(xié)議和內(nèi)容交換等。
面向服務(wù)的架構(gòu)
面向服務(wù)架構(gòu)(Service-Oriented Architecture侦铜,SOA
)又稱“面向服務(wù)的體系結(jié)構(gòu)”专甩,是Gartner于2O世紀(jì)9O年代中期提出的面向服務(wù)架構(gòu)的概念。
面向服務(wù)架構(gòu)钉稍,從語義上說涤躲,它與面向過程、面向?qū)ο蠊蔽础⒚嫦蚪M件一樣种樱,是一種軟件組建及開發(fā)的方式。與以往的軟件開發(fā)俊卤、架構(gòu)模式一樣嫩挤,SOA 只是一種體系、一種思想瘾蛋,而不是某種具體的軟件產(chǎn)品俐镐。
這里,我們通過一個例子來解釋一下到底什么是 SOA哺哼?如何做到 SOA佩抹?
什么是 SOA
SOA 也可以說是一種是設(shè)計原則(模式),那么它包含哪些內(nèi)容呢取董?事實上棍苹,這方面并沒有最標(biāo)準(zhǔn)的答案,多數(shù)是遵從著名 SOA 專家 Thomas Erl 的歸納:
- 標(biāo)準(zhǔn)化的服務(wù)契約 Standardized service contract
- 服務(wù)的松耦合 Service loose coupling
- 服務(wù)的抽象 Service abstraction
- 服務(wù)的可重用性 Service reusability
- 服務(wù)的自治性 Service autonomy
- 服務(wù)的無狀態(tài)性 Service statelessness
- 服務(wù)的可發(fā)現(xiàn)性 Service discoverability
- 服務(wù)的可組合性 Service composability
這些原則總的來說要達到的目的是:提高軟件的重用性茵汰,減少開發(fā)和維護的成本枢里,最終增加一個公司業(yè)務(wù)的敏捷度。既然是面向服務(wù)的架構(gòu),那么我們就先來定義一個服務(wù)栏豺,
public interface Echo {
String echo(String text);
}
public class EchoImpl implements Echo {
public String echo(String text) {
return text;
}
}
上面這段代碼相信有過 JavaWeb 開發(fā)經(jīng)驗的人都不會陌生彬碱。就是定義了一個服務(wù)的接口和實現(xiàn)。
那么奥洼,定義了服務(wù)巷疼,我們就做到了 SOA 了么?
我們用 Thomas Erl 定義的原則來對比一下灵奖,用松耦合和可重用這幾個原則來嘗試分析一下上面 Echo 示例:
- Echo 的服務(wù)契約是用 Java 接口定義嚼沿,而不是一種與平臺和語言無關(guān)的標(biāo)準(zhǔn)化協(xié)議,如 WSDL瓷患,CORBA IDL骡尽。當(dāng)然可以抬杠,Java 也是行業(yè)標(biāo)準(zhǔn)擅编,甚至全國牙防組一致認(rèn)定的東西也是行業(yè)標(biāo)準(zhǔn)攀细。
- Java 接口大大加重了與 Service 客戶端的耦合度,即要求客戶端必須也是 Java沙咏,或者 JVM 上的動態(tài)語言(如Groovy辨图、Jython)等等……
- 同時,Echo 是一個 Java 的本地接口肢藐,就要求調(diào)用者最好在同一個 JVM 進程之內(nèi)……
- Echo 的業(yè)務(wù)邏輯雖然簡單獨立,但以上技術(shù)方面的局限就導(dǎo)致它無法以后在其他場合被輕易重用吱韭,比如分布式環(huán)境吆豹,異構(gòu)平臺等等 ESB 是 SCA 思想實現(xiàn)的基礎(chǔ)設(shè)施。ESB 主要作用是集中注冊發(fā)布服務(wù)理盆,為服務(wù)與傳輸協(xié)議之間解耦痘煤。并不是所有的 SOA 架構(gòu)都需要 ESB,ESB 是 SCA 特有的猿规。當(dāng)然任何符合 ESB 特征的解決方式都可以稱之為 ESB衷快,也不僅僅是 SCA 內(nèi)部的。
因此姨俩,我們可以認(rèn)為 Echo 并不太符合 SOA 的基本設(shè)計原則蘸拔。
實現(xiàn) SOA
修改一下上面的 Echo,添加 Java EE 的 @WebServices
注解
@WebServices
public class EchoImpl implements Echo {
public String echo(String text) {
return text;
}
}
現(xiàn)在將 Echo 發(fā)布為 Java WebServices环葵,并由底層框架自動生成 WSDL 來作為標(biāo)準(zhǔn)化的服務(wù)契約调窍,這樣就能與遠程的各種語言和平臺互操作了,較好的解決了上面提到的松耦合和可重用的問題张遭。按照一般的理解邓萨,Echo 似乎就成為比較理想的 SOA service了。
使用 WebServices 只是一種相對簡單的方案,SOA 的最常見的解決方案是 SCA缔恳,其次還有 JBI宝剖,BPEL 等。ESB 是 SCA 思想實現(xiàn)的基礎(chǔ)設(shè)施歉甚。ESB 主要作用是集中注冊發(fā)布服務(wù)万细,為服務(wù)與傳輸協(xié)議之間解耦。關(guān)于 SCA 和 ESB 并不是本文的重點铃芦,感興趣的朋友可以從網(wǎng)絡(luò)上獲取更多資料雅镊。(可以從上圖中看到 ESB 在整個 SOA 架構(gòu)中所扮演的角色)
面向?qū)ο蠛兔嫦蚍?wù)的對比
面向?qū)ο螅?code>OO)和面向服務(wù)(SO
)在基礎(chǔ)理念上有大量共通之處,比如都盡可能追求抽象刃滓、封裝和低耦合仁烹。
但 SO 相對于 OO,又有非常不同的典型應(yīng)用場景咧虎,比如:
- 多數(shù) OO 接口(interface)都只被有限的人使用(比如團隊和部門內(nèi))卓缰,而 SO 接口(或者叫契約)一般來說都不應(yīng)該對使用者的范圍作出太多的限定和假設(shè)(可以是不同部門,不同企業(yè)砰诵,不同國家)征唬。還記得貝佐斯原則嗎?“團隊必須做好規(guī)劃與設(shè)計茁彭,以便未來把接口開放給全世界的程序員总寒,沒有任何例外”。
- 多數(shù) OO 接口都只在進程內(nèi)被訪問理肺,而 SO 接口通常都是被遠程調(diào)用摄闸。
簡單講,就是 SO 接口使用范圍比一般 OO 接口可能廣泛得多妹萨。我們用網(wǎng)站打個比方:一個大型網(wǎng)站的 web 界面就是它整個系統(tǒng)入口點和邊界年枕,可能要面對全世界的訪問者(所以經(jīng)常會做國際化之類的工作),而系統(tǒng)內(nèi)部傳統(tǒng)的 OO 接口和程序則被隱藏在 web 界面之后乎完,只被內(nèi)部較小范圍使用熏兄。而理想的 SO 接口和 web 界面一樣,也是變成系統(tǒng)入口和邊界树姨,可能要對全世界開發(fā)者開放摩桶,因此 SO 在設(shè)計開發(fā)之中與 OO 相比其實會有很多不同。
微服務(wù)架構(gòu)
微服務(wù)架構(gòu)(MicroService
)是一種服務(wù)化架構(gòu)風(fēng)格娃弓,通過將功能分散到各個離散的服務(wù)中以實現(xiàn)對解決方案的解耦典格。微服務(wù)架構(gòu)強調(diào)的第一個重點就是業(yè)務(wù)系統(tǒng)需要徹底的組件化和服務(wù)化(這也是我們?yōu)槭裁匆冉榻B組件化和服務(wù)化的原因)。微服務(wù)的誕生并非偶然台丛。它是互聯(lián)網(wǎng)高速發(fā)展耍缴,敏捷砾肺、精益、持續(xù)交付方法論的深入人心防嗡,虛擬化技術(shù)與 DevOps 文化的快速發(fā)展以及傳統(tǒng)單塊架構(gòu)無法適應(yīng)快速變化等多重因素的推動下所誕生的產(chǎn)物变汪。
微服務(wù)的流行,Martin 功不可沒蚁趁,先看看他是如何定義微服務(wù)的:
- 一些列的獨立的服務(wù)共同組成系統(tǒng)
- 單獨部署裙盾,跑在自己的進程里
- 每個服務(wù)為獨立的業(yè)務(wù)開發(fā)
- 分布式的管理
Martin 自己也說了,每個人對微服務(wù)都可以有自己的理解他嫡,不過大概的標(biāo)準(zhǔn)還是有一些的番官。
- 分布式服務(wù)組成的系統(tǒng)
- 按照業(yè)務(wù)而不是技術(shù)來劃分組織
- 做有生命的產(chǎn)品而不是項目
- Smart endpoints and dumb pipes(我的理解是強服務(wù)個體和弱通信)
- 自動化運維(DevOps)
- 容錯
- 快速演化
SOA 和微服務(wù)
看了 SOA 和微服務(wù),很多人會認(rèn)為這不就是一回事兒么钢属。其實 SOA 和微服務(wù)就是差不多的徘熔。
- SOA 關(guān)注的是服務(wù)重用,微服務(wù)在關(guān)注服務(wù)重用的同時淆党,也同時關(guān)注快速交付酷师;
- 微服務(wù)不再強調(diào)傳統(tǒng) SOA 架構(gòu)里面比較重的 ESB 企業(yè)服務(wù)總線。微服務(wù)把所有的“思考”邏輯包括路由染乌、消息解析等放在服務(wù)內(nèi)部山孔,去掉一個大一統(tǒng)的 ESB,服務(wù)間輕通信荷憋,是比 SOA 更徹底的拆分台颠。