面試都在問(wèn)的微服務(wù),一文帶你徹底搞懂!
單體式應(yīng)用程序
與微服務(wù)相對(duì)的另一個(gè)概念是傳統(tǒng)的「單體式應(yīng)用程序」( Monolithic application ),單體式應(yīng)用內(nèi)部包含了所有需要的服務(wù)。而且各個(gè)服務(wù)功能模塊有很強(qiáng)的耦合性,也就是相互依賴(lài)彼此,很難拆分和擴(kuò)容。
在座的各位都寫(xiě)過(guò)單體程序,給大家舉個(gè)栗子,剛開(kāi)始寫(xiě)代碼你寫(xiě)helloworld 程序就是單體程序,一個(gè)程序包含所有功能,雖然helloworld 功能很簡(jiǎn)單。
單體應(yīng)用程序的優(yōu)點(diǎn)
- 開(kāi)發(fā)簡(jiǎn)潔,功能都在單個(gè)程序內(nèi)部,便于軟件設(shè)計(jì)和開(kāi)發(fā)規(guī)劃。
- 容易部署,程序單一不存在分布式集群的復(fù)雜部署環(huán)境,降低了部署難度。
- 容易測(cè)試,沒(méi)有各種復(fù)雜的服務(wù)調(diào)用關(guān)系,都是內(nèi)部調(diào)用方便測(cè)試。
單體應(yīng)用程序的缺點(diǎn)
單體程序的缺點(diǎn)一開(kāi)始不是特別明顯,項(xiàng)目剛開(kāi)始需求少,業(yè)務(wù)邏輯簡(jiǎn)單,寫(xiě)代碼一時(shí)爽,一直爽。噩夢(mèng)從業(yè)務(wù)迭代更新,系統(tǒng)日益龐大開(kāi)始,前期的爽沒(méi)有了,取而代之的是軟件維護(hù)和迭代更新的無(wú)盡痛苦。
單體架構(gòu)
由于單體式應(yīng)用程序就像一個(gè)大型容器一樣,里面放置了許多服務(wù),且他們都是密不可分的,這導(dǎo)致應(yīng)用程序在擴(kuò)展時(shí)必須以「應(yīng)用程序」為單位。
當(dāng)里面有個(gè)業(yè)務(wù)模塊負(fù)載過(guò)高時(shí),并不能夠單獨(dú)擴(kuò)展該服務(wù),必須擴(kuò)展整個(gè)應(yīng)用程序(就是這么霸道),這可能導(dǎo)致額外的資源浪費(fèi)。
此外,單體式應(yīng)用程序由于服務(wù)之間的緊密度、相依性過(guò)高,這將導(dǎo)致測(cè)試、升級(jí)有所困難,且開(kāi)發(fā)曲線(xiàn)有可能會(huì)在后期大幅度地上升,令開(kāi)發(fā)不易。相較之下「微服務(wù)架構(gòu)」能夠解決這個(gè)問(wèn)題。
微服務(wù)
微服務(wù) (Microservices) 就是一些協(xié)同工作小而自治的服務(wù)。
❝ 2014年,Martin Fowler 與 James Lewis 共同提出了微服務(wù)的概念,定義了微服務(wù)是由以單一應(yīng)用程序構(gòu)成的小服務(wù),自己擁有自己的行程與輕量化處理,服務(wù)依業(yè)務(wù)功能設(shè)計(jì),以全自動(dòng)的方式部署,與其他服務(wù)使用 HTTP API 通信。同時(shí)服務(wù)會(huì)使用最小的規(guī)模的集中管理 (例如 Docker) 能力,服務(wù)可以用不同的編程語(yǔ)言與數(shù)據(jù)庫(kù)等組件實(shí)現(xiàn) ?!妇S基百科」 ❞
舉例
還是拿前面的 helloworld 程序來(lái)舉栗子,想象一下你是 helloworld 公司的 CTO(老板還缺人嗎?會(huì)寫(xiě)代碼的那種),假設(shè)你們公司的 helloworld 業(yè)務(wù)遍布全球,需要編寫(xiě)不同語(yǔ)種的 helloworld 版本,分別輸出英語(yǔ)、日語(yǔ)、法語(yǔ)、俄語(yǔ)...現(xiàn)在世界有6000多種語(yǔ)言(奇怪的知識(shí)又增加了)。
有人會(huì)說(shuō)這還不簡(jiǎn)單我用switch case語(yǔ)句就完事了,同學(xué),不要較真我就是舉個(gè)例子,現(xiàn)實(shí)中的業(yè)務(wù)比 helloworld 復(fù)雜多了。好了,我們姑且認(rèn)為按語(yǔ)言輸出是個(gè)龐大復(fù)雜的工作,這時(shí)候就可以用微服務(wù)架構(gòu)了,架構(gòu)圖如下:
微服務(wù)架構(gòu)
微服務(wù)與SOA
「面向服務(wù)的體系結(jié)構(gòu)」 SOA (Service-Oriented Architecture) 聽(tīng)起來(lái)和微服務(wù)很像,但 SOA 早期均使用了總線(xiàn)模式,這種總線(xiàn)模式是與某種技術(shù)棧強(qiáng)綁定的,比如:J2EE。這導(dǎo)致很多企業(yè)的遺留系統(tǒng)很難對(duì)接,切換時(shí)間太長(zhǎng),成本太高,新系統(tǒng)穩(wěn)定性的收斂也需要一些時(shí)間,最終 SOA 看起來(lái)很美,但卻成為了企業(yè)級(jí)奢侈品,中小公司都望而生畏。
此外,實(shí)施SOA時(shí)會(huì)遇到很多問(wèn)題,比如通信協(xié)議(例如SOAP)的選擇、第三方中間件如何選擇、服務(wù)粒度如何確定等,目前也存在一些關(guān)于如何劃分系統(tǒng)的指導(dǎo)性原則,但其中有很多都是錯(cuò)誤的。SOA并沒(méi)有告訴你如何劃分單體應(yīng)用成微服務(wù),所以在實(shí)施SOA時(shí)會(huì)遇到很多問(wèn)題。
這些問(wèn)題在微服務(wù)框架中得到很好的解決,你可以認(rèn)為微服務(wù)架構(gòu)是SOA的一種特定方法。
微服務(wù)架構(gòu)
合久必分,鑒于「單體應(yīng)用程序」有上述的缺點(diǎn),單個(gè)應(yīng)用程序被劃分成各種小的、互相連接的微服務(wù),一個(gè)微服務(wù)完成一個(gè)比較單一的功能,相互之間保持獨(dú)立和解耦合,這就是微服務(wù)架構(gòu)。
微服務(wù)優(yōu)點(diǎn)
相對(duì)于單體服務(wù),微服務(wù)有很多優(yōu)點(diǎn),這里列舉幾個(gè)主要的好處
技術(shù)異構(gòu)性
不同服務(wù)內(nèi)部的開(kāi)發(fā)技術(shù)可以不一致,你可以用java來(lái)開(kāi)發(fā)helloworld服務(wù)A,用golang來(lái)開(kāi)發(fā)helloworld服務(wù)B,大家再也不用為哪種語(yǔ)言是世界上最好的語(yǔ)言而爭(zhēng)論不休。
為不同的服務(wù)選擇最適合該服務(wù)的技術(shù),系統(tǒng)中不同部分也可以使用不同的存儲(chǔ)技術(shù),比如A服務(wù)可以選擇redis存儲(chǔ),B服務(wù)你可以選擇用MySQL存儲(chǔ),這都是允許的,你的服務(wù)你做主。
隔離性
一個(gè)服務(wù)不可用不會(huì)導(dǎo)致另一個(gè)服務(wù)也癱瘓,因?yàn)楦鱾€(gè)服務(wù)是相互獨(dú)立和自治的系統(tǒng)。這在單體應(yīng)用程序中是做不到的,單體應(yīng)用程序中某個(gè)模塊癱瘓,必將導(dǎo)致整個(gè)系統(tǒng)不可用,當(dāng)然,單體程序也可以在不同機(jī)器上部署同樣的程序來(lái)實(shí)現(xiàn)備份,不過(guò),同樣存在上面說(shuō)的資源浪費(fèi)問(wèn)題。
可擴(kuò)展性
龐大的單體服務(wù)如果出現(xiàn)性能瓶頸只能對(duì)軟件整體進(jìn)行擴(kuò)展,可能真正影響性能的只是其中一個(gè)很小的模塊,我們也不得不付出升級(jí)整個(gè)應(yīng)用的代價(jià)。這在微服務(wù)架構(gòu)中得到了改善,你可以只對(duì)那些影響性能的服務(wù)做擴(kuò)展升級(jí),這樣對(duì)癥下藥的效果是很好的。
簡(jiǎn)化部署
如果你的服務(wù)是一個(gè)超大的單體服務(wù),有幾百萬(wàn)行代碼,即使修改了幾行代碼也要重新編譯整個(gè)應(yīng)用,這顯然是非常繁瑣的,而且軟件變更帶來(lái)的不確定性非常高,軟件部署的影響也非常大。在微服務(wù)架構(gòu)中,各個(gè)服務(wù)的部署是獨(dú)立的,如果真出了問(wèn)題也只是影響單個(gè)服務(wù),可以快速回滾版本解決。
易優(yōu)化
微服務(wù)架構(gòu)中單個(gè)服務(wù)的代碼量不會(huì)很大,這樣當(dāng)你需要重構(gòu)或者優(yōu)化這部分服務(wù)的時(shí)候,就會(huì)容易很多,畢竟,代碼量越少意味著代碼改動(dòng)帶來(lái)的影響越可控。
微服務(wù)缺點(diǎn)
我們上面一直在強(qiáng)調(diào)微服務(wù)的好處,但是,微服務(wù)架構(gòu)不是萬(wàn)能的,并不能解決所有問(wèn)題,其實(shí)這也是微服務(wù)把單體應(yīng)用拆分成很多小的分布式服務(wù)導(dǎo)致的,所謂人多手雜,服務(wù)多起來(lái)管理的不好各種問(wèn)題就來(lái)了。
為了解決微服務(wù)的缺點(diǎn),前輩們提出了下面這些概念。
服務(wù)注冊(cè)與發(fā)現(xiàn)
微服務(wù)之間相互調(diào)用完成整體業(yè)務(wù)功能,如何在眾多微服務(wù)中找到正確的目標(biāo)服務(wù)地址,這就是所謂「服務(wù)發(fā)現(xiàn)」功能。
常用的做法是服務(wù)提供方啟動(dòng)的時(shí)候把自己的地址上報(bào)給「服務(wù)注冊(cè)中心」,這就是「服務(wù)注冊(cè)」。服務(wù)調(diào)用方「訂閱」服務(wù)變更「通知」,動(dòng)態(tài)的接收服務(wù)注冊(cè)中心推送的服務(wù)地址列表,以后想找哪個(gè)服務(wù)直接發(fā)給他就可以。
服務(wù)發(fā)現(xiàn)
服務(wù)監(jiān)控
單體程序的監(jiān)控運(yùn)維還好說(shuō),大型微服務(wù)架構(gòu)的服務(wù)運(yùn)維是一大挑戰(zhàn)。服務(wù)運(yùn)維人員需要實(shí)時(shí)的掌握服務(wù)運(yùn)行中的各種狀態(tài),最好有個(gè)控制面板能看到服務(wù)的內(nèi)存使用率、調(diào)用次數(shù)、健康狀況等信息。
這就需要我們有一套完備的服務(wù)監(jiān)控體系,包括拓?fù)潢P(guān)系、監(jiān)控(Metrics)、日志監(jiān)控(Logging)、調(diào)用追蹤(Trace)、告警通知、健康檢查等,防患于未然。
服務(wù)容錯(cuò)
任何服務(wù)都不能保證100%不出問(wèn)題,生產(chǎn)環(huán)境復(fù)雜多變,服務(wù)運(yùn)行過(guò)程中不可避免的發(fā)生各種故障(宕機(jī)、過(guò)載等等),工程師能夠做的是在故障發(fā)生時(shí)盡可能降低影響范圍、盡快恢復(fù)正常服務(wù)。
聰明的程序員引入了「熔斷、隔離、限流和降級(jí)、超時(shí)機(jī)制」等「服務(wù)容錯(cuò)」機(jī)制來(lái)保證服務(wù)持續(xù)可用性。
服務(wù)安全
有些服務(wù)的敏感數(shù)據(jù)存在安全問(wèn)題,「服務(wù)安全」就是對(duì)敏感服務(wù)采用安全鑒權(quán)機(jī)制,對(duì)服務(wù)的訪(fǎng)問(wèn)需要進(jìn)行相應(yīng)的身份驗(yàn)證和授權(quán),防止數(shù)據(jù)泄露的風(fēng)險(xiǎn),安全是一個(gè)長(zhǎng)久的話(huà)題,在微服務(wù)中也有很多工作要做。
服務(wù)治理
說(shuō)到「治理」一般都是有問(wèn)題才需要治理,我們平常說(shuō)環(huán)境治理、污染治理一個(gè)意思,微服務(wù)架構(gòu)中的微服務(wù)越來(lái)越多,上面說(shuō)的那些問(wèn)題就更加顯現(xiàn),為了解決上面微服務(wù)架構(gòu)缺陷「服務(wù)治理」就出現(xiàn)了。
微服務(wù)的那些問(wèn)題都要公司技術(shù)團(tuán)隊(duì)自己解決的話(huà),如果不是大型公司有成熟的技術(shù)團(tuán)隊(duì),估計(jì)會(huì)很頭大。幸好,有巨人的肩膀可以借給我們站上去,通過(guò)引入「微服務(wù)框架」來(lái)幫助我們完成服務(wù)治理。
微服務(wù)框架
介紹一些業(yè)界比較成熟的微服務(wù)框架。
Tars
騰訊內(nèi)部使用的微服務(wù)架構(gòu) TAF(Total Application Framework)多年的實(shí)踐成果總結(jié)而成的開(kāi)源項(xiàng)目。僅支持 C++ 語(yǔ)言,目前在騰訊內(nèi)部應(yīng)用也非常廣泛。2017 年對(duì)外開(kāi)源,僅支持 C++ 語(yǔ)言。
源碼:https://github.com/TarsCloud/Tars/
TARS架構(gòu)圖|來(lái)源github.com/TarsCloud
本命鵝廠(chǎng) TARS 框架詳細(xì)介紹 PPT 已下載,不想自己麻煩去找的同學(xué),在我公眾號(hào)「后端技術(shù)學(xué)堂」回復(fù)「tars」獲取。
Dubbo
是阿里巴巴公司開(kāi)源的一個(gè)Java高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過(guò)高性能的 RPC 實(shí)現(xiàn)服務(wù)的輸出和輸入功能,可以和 Spring框架無(wú)縫集成。Apache Dubbo |ˈdʌbəʊ| 是一款高性能、輕量級(jí)的開(kāi)源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn) 。2011 年末對(duì)外開(kāi)源,僅支持 Java 語(yǔ)言。
官網(wǎng):http://dubbo.apache.org/zh-cn/
Dubbo架構(gòu)圖|圖片來(lái)源dubbo.apache.org
Motan
是新浪微博開(kāi)源的一個(gè)Java 框架。Motan 在微博平臺(tái)中已經(jīng)廣泛應(yīng)用,每天為數(shù)百個(gè)服務(wù)完成近千億次的調(diào)用。于 2016 年對(duì)外開(kāi)源,僅支持 Java 語(yǔ)言。
官方指南:https://github.com/weibocom/motan/wiki/zh_userguide
Motan框架|圖片來(lái)源github.com/weibocom/motan
gRPC
是Google開(kāi)發(fā)的高性能、通用的開(kāi)源RPC框架,其由Google主要面向移動(dòng)應(yīng)用開(kāi)發(fā)并基于HTTP/2協(xié)議標(biāo)準(zhǔn)而設(shè)計(jì),基于ProtoBuf(Protocol Buffers)序列化協(xié)議開(kāi)發(fā)。本身它不是分布式的,所以要實(shí)現(xiàn)上面的框架的功能需要進(jìn)一步的開(kāi)發(fā)。2015 年對(duì)外開(kāi)源的跨語(yǔ)言 RPC 框架,支持多種語(yǔ)言。
中文教程:https://doc.oschina.net/grpc?t=58008
gRPC架構(gòu)圖|圖片來(lái)源www.grpc.io
thrift
最初是由 Facebook 開(kāi)發(fā)的內(nèi)部系統(tǒng)跨語(yǔ)言的高性能 RPC 框架,2007 年貢獻(xiàn)給了 Apache 基金,成為 Apache 開(kāi)源項(xiàng)目之一, 跟 gRPC 一樣,Thrift 也有一套自己的接口定義語(yǔ)言 IDL,可以通過(guò)代碼生成器,生成各種編程語(yǔ)言的 Client 端和 Server 端的 SDK 代碼,支持多種語(yǔ)言。
thrift架構(gòu) | 圖片來(lái)源wikimedia
微服務(wù)框架和RPC
很多人對(duì)這兩個(gè)概念有點(diǎn)混淆,微服務(wù)框架上面我們說(shuō)過(guò)了,我們?cè)賮?lái)看下RPC的概念。
什么是RPC
RPC (Remote Procedure Call)遠(yuǎn)程過(guò)程調(diào)用是一個(gè)計(jì)算機(jī)通信協(xié)議。我們一般的程序調(diào)用是本地程序內(nèi)部的調(diào)用,RPC允許你像調(diào)用本地函數(shù)一樣去調(diào)用另一個(gè)程序的函數(shù),這中間會(huì)涉及網(wǎng)絡(luò)通信和進(jìn)程間通信,但你無(wú)需知道實(shí)現(xiàn)細(xì)節(jié),RPC框架為你屏蔽了底層實(shí)現(xiàn)。RPC是一種服務(wù)器-客戶(hù)端(Client/Server)模式,經(jīng)典實(shí)現(xiàn)是一個(gè)通過(guò)「發(fā)送請(qǐng)求-接受回應(yīng)」進(jìn)行信息交互的系統(tǒng)。
兩者關(guān)系
RPC和微服務(wù)框架的關(guān)系?!肝⒎?wù)框架」一般都包含了RPC的實(shí)現(xiàn)和一系列「服務(wù)治理」能力,是一套軟件開(kāi)發(fā)框架。我們可以基于這個(gè)框架之上實(shí)現(xiàn)自己的微服務(wù),方便的利用微服務(wù)框架提供的「服務(wù)治理」能力和RPC能力,所以微服務(wù)框架也被有些人稱(chēng)作RPC框架。
下一代微服務(wù)架構(gòu)
Service Mesh(服務(wù)網(wǎng)格)被認(rèn)為是下一代微服務(wù)架構(gòu),Service Mesh并沒(méi)有給我們帶來(lái)新的功能,它是用于解決其他工具已經(jīng)解決過(guò)的服務(wù)網(wǎng)絡(luò)調(diào)用、限流、熔斷和監(jiān)控等問(wèn)題,只不過(guò)這次是在Cloud Native 的 kubernetes 環(huán)境下的實(shí)現(xiàn)。
特點(diǎn)
Service Mesh 有如下幾個(gè)特點(diǎn):
- 應(yīng)用程序間通訊的中間層
- 輕量級(jí)網(wǎng)絡(luò)代理
- 應(yīng)用程序無(wú)感知
- 解耦應(yīng)用程序的重試/超時(shí)、監(jiān)控、追蹤和服務(wù)發(fā)現(xiàn)
目前兩款流行的 Service Mesh 開(kāi)源軟件 [Istio](https://istio.io/) 和 [Linkerd](https://linkerd.io/)都可以直接在kubernetes 中集成,其中Linkerd已經(jīng)成為云原生計(jì)算基金會(huì) CNCF (Cloud Native Computing Foundation) 成員。
Why Service Mesh
為什么現(xiàn)有微服務(wù)架構(gòu)已經(jīng)解決的問(wèn)題還要用Service Mesh呢?這個(gè)問(wèn)題問(wèn)的好。
回答問(wèn)題之前,先看下istio.io上對(duì)service mesh的解釋?zhuān)矣X(jué)得挺好的,摘抄出來(lái):
❝ As a service mesh grows in size and complexity, it can become harder to understand and manage. Its requirements can include discovery, load balancing, failure recovery, metrics, and monitoring. A service mesh also often has more complex operational requirements, like A/B testing, canary rollouts, rate limiting, access control, and end-to-end authentication.
makes it easy to create a network of deployed services with load balancing, service-to-service authentication, monitoring, and more, **with few or no code changes in service code. ** ❞
試著總結(jié)一下:隨著微服務(wù)的增多復(fù)雜程度也增加,管理變得更加困難,微服務(wù)架構(gòu)雖然解決了「網(wǎng)絡(luò)調(diào)用、限流、熔斷和監(jiān)控」等問(wèn)題,但大多數(shù)框架和開(kāi)源軟件對(duì)原有業(yè)務(wù)是侵入式的,也就是需要在業(yè)務(wù)服務(wù)程序中集成相關(guān)的「服務(wù)治理」組件。
Service Mesh之于微服務(wù),就像TCP/IP之于互聯(lián)網(wǎng),TCP/IP為網(wǎng)絡(luò)通信提供了面向連接的、可靠的、基于字節(jié)流的基礎(chǔ)通信功能,你不再需要關(guān)心底層的重傳、校驗(yàn)、流量控制、擁塞控制。
用了Service Mesh你也不必去操心「服務(wù)治理」的細(xì)節(jié),不需要對(duì)服務(wù)做特殊的改造,所有業(yè)務(wù)之外的功能都由Service Mesh幫你去做了。它就像一個(gè)輕量級(jí)網(wǎng)絡(luò)代理 對(duì)應(yīng)用程序來(lái)說(shuō)是透明,所有應(yīng)用程序間的流量都會(huì)通過(guò)它,所以對(duì)應(yīng)用程序流量的控制都可以在 serivce mesh 中實(shí)現(xiàn) 。
Service Mesh架構(gòu)|圖片來(lái)自:Pattern: Service Mesh
寫(xiě)在最后
在IT世界沒(méi)有什么技術(shù)是永不過(guò)時(shí)的,微服務(wù)架構(gòu)的演進(jìn)就是一個(gè)例子,從單體程序到微服務(wù)架構(gòu),再到service mesh架構(gòu),我不知道下一個(gè)技術(shù)迭代點(diǎn)是什么時(shí)候,但可以肯定微服務(wù)架構(gòu)還會(huì)演進(jìn),IT人更應(yīng)該建立終身學(xué)習(xí)的習(xí)慣。
當(dāng)然更重要的是擁有對(duì)技術(shù)的熱情,熱于擁抱變化、接受新技術(shù),當(dāng)看到新技術(shù)我是興奮的,內(nèi)心os是厲害了,還能這么玩!,希望你也有這樣的熱情,而不僅僅是面向工資編程,這樣生活會(huì)更有樂(lè)趣。
老規(guī)矩。感謝各位的閱讀,文章的目的是分享對(duì)知識(shí)的理解,技術(shù)類(lèi)文章我都會(huì)反復(fù)求證以求最大程度保證準(zhǔn)確性,若文中出現(xiàn)明顯紕漏也歡迎指出,我們一起在探討中學(xué)習(xí)。








































