一、微服務(wù)概況
1. 什么是微服務(wù)
在介紹微服務(wù)時(shí),首先得先理解什么是微服務(wù),顧名思義,微服務(wù)得從兩個(gè)方面去理解,什么是“微”、什么是“服務(wù)”, 微 狹義來(lái)講就是體積小、著名的“2 pizza 團(tuán)隊(duì)”很好的詮釋了這一解釋(2 pizza 團(tuán)隊(duì)最早是亞馬遜 CEO Bezos提出來(lái)的,意思是說(shuō)單個(gè)服務(wù)的設(shè)計(jì),所有參與人從設(shè)計(jì)、開發(fā)、測(cè)試、運(yùn)維所有人加起來(lái) 只需要2個(gè)披薩就夠了 )。 而所謂服務(wù),一定要區(qū)別于系統(tǒng),服務(wù)一個(gè)或者一組相對(duì)較小且獨(dú)立的功能單元,是用戶可以感知最小功能集。
2. 微服務(wù)由來(lái)
微服務(wù)最早由Martin Fowler與James Lewis于2014年共同提出,微服務(wù)架構(gòu)風(fēng)格是一種使用一套小服務(wù)來(lái)開發(fā)單個(gè)應(yīng)用的方式途徑,每個(gè)服務(wù)運(yùn)行在自己的進(jìn)程中,并使用輕量級(jí)機(jī)制通信,通常是HTTP API,這些服務(wù)基于業(yè)務(wù)能力構(gòu)建,并能夠通過自動(dòng)化部署機(jī)制來(lái)獨(dú)立部署,這些服務(wù)使用不同的編程語(yǔ)言實(shí)現(xiàn),以及不同數(shù)據(jù)存儲(chǔ)技術(shù),并保持最低限度的集中式管理。
3. 為什么需要微服務(wù)?
在傳統(tǒng)的IT行業(yè)軟件大多都是各種獨(dú)立系統(tǒng)的堆砌,這些系統(tǒng)的問題總結(jié)來(lái)說(shuō)就是擴(kuò)展性差,可靠性不高,維護(hù)成本高。到后面引入了SOA服務(wù)化,但是,由于 SOA 早期均使用了總線模式,這種總線模式是與某種技術(shù)棧強(qiáng)綁定的,比如:J2EE。這導(dǎo)致很多企業(yè)的遺留系統(tǒng)很難對(duì)接,切換時(shí)間太長(zhǎng),成本太高,新系統(tǒng)穩(wěn)定性的收斂也需要一些時(shí)間。最終 SOA 看起來(lái)很美,但卻成為了企業(yè)級(jí)奢侈品,中小公司都望而生畏。
3.1 最期的單體架構(gòu)帶來(lái)的問題
單體架構(gòu)在規(guī)模比較小的情況下工作情況良好,但是隨著系統(tǒng)規(guī)模的擴(kuò)大,它暴露出來(lái)的問題也越來(lái)越多,主要有以下幾點(diǎn):
1.復(fù)雜性逐漸變高
比如有的項(xiàng)目有幾十萬(wàn)行代碼,各個(gè)模塊之間區(qū)別比較模糊,邏輯比較混亂,代碼越多復(fù)雜性越高,越難解決遇到的問題。
2.技術(shù)債務(wù)逐漸上升
公司的人員流動(dòng)是再正常不過的事情,有的員工在離職之前,疏于代碼質(zhì)量的自我管束,導(dǎo)致留下來(lái)很多坑,由于單體項(xiàng)目代碼量龐大的驚人,留下的坑很難被發(fā)覺,這就給新來(lái)的員工帶來(lái)很大的煩惱,人員流動(dòng)越大所留下的坑越多,也就是所謂的技術(shù)債務(wù)越來(lái)越多。
3.部署速度逐漸變慢
這個(gè)就很好理解了,單體架構(gòu)模塊非常多,代碼量非常龐大,導(dǎo)致部署項(xiàng)目所花費(fèi)的時(shí)間越來(lái)越多,曾經(jīng)有的項(xiàng)目啟動(dòng)就要一二十分鐘,這是多么恐怖的事情啊,啟動(dòng)幾次項(xiàng)目一天的時(shí)間就過去了,留給開發(fā)者開發(fā)的時(shí)間就非常少了。
4.阻礙技術(shù)創(chuàng)新
比如以前的某個(gè)項(xiàng)目使用struts2寫的,由于各個(gè)模塊之間有著千絲萬(wàn)縷的聯(lián)系,代碼量大,邏輯不夠清楚,如果現(xiàn)在想用spring mvc來(lái)重構(gòu)這個(gè)項(xiàng)目將是非常困難的,付出的成本將非常大,所以更多的時(shí)候公司不得不硬著頭皮繼續(xù)使用老的struts架構(gòu),這就阻礙了技術(shù)的創(chuàng)新。
5.無(wú)法按需伸縮
比如說(shuō)電影模塊是CPU密集型的模塊,而訂單模塊是IO密集型的模塊,假如我們要提升訂單模塊的性能,比如加大內(nèi)存、增加硬盤,但是由于所有的模塊都在一個(gè)架構(gòu)下,因此我們?cè)跀U(kuò)展訂單模塊的性能時(shí)不得不考慮其它模塊的因素,因?yàn)槲覀儾荒芤驗(yàn)閿U(kuò)展某個(gè)模塊的性能而損害其它模塊的性能,從而無(wú)法按需進(jìn)行伸縮。
3.2 微服務(wù)與單體架構(gòu)區(qū)別
單體架構(gòu)所有的模塊全都耦合在一塊,代碼量大,維護(hù)困難,微服務(wù)每個(gè)模塊就相當(dāng)于一個(gè)單獨(dú)的項(xiàng)目,代碼量明顯減少,遇到問題也相對(duì)來(lái)說(shuō)比較好解決。
單體架構(gòu)所有的模塊都共用一個(gè)數(shù)據(jù)庫(kù),存儲(chǔ)方式比較單一,微服務(wù)每個(gè)模塊都可以使用不同的存儲(chǔ)方式(比如有的用redis,有的用mysql等),數(shù)據(jù)庫(kù)也是單個(gè)模塊對(duì)應(yīng)自己的數(shù)據(jù)庫(kù)。
單體架構(gòu)所有的模塊開發(fā)所使用的技術(shù)一樣,微服務(wù)每個(gè)模塊都可以使用不同的開發(fā)技術(shù),開發(fā)模式更靈活。
4. 微服務(wù)本質(zhì)
微服務(wù),關(guān)鍵其實(shí)不僅僅是微服務(wù)本身,而是系統(tǒng)要提供一套基礎(chǔ)的架構(gòu),這種架構(gòu)使得微服務(wù)可以獨(dú)立的部署、運(yùn)行、升級(jí),不僅如此,這個(gè)系統(tǒng)架構(gòu)還讓微服務(wù)與微服務(wù)之間在結(jié)構(gòu)上“松耦合”,而在功能上則表現(xiàn)為一個(gè)統(tǒng)一的整體。這種所謂的“統(tǒng)一的整體”表現(xiàn)出來(lái)的是統(tǒng)一風(fēng)格的界面,統(tǒng)一的權(quán)限管理,統(tǒng)一的安全策略,統(tǒng)一的上線過程,統(tǒng)一的日志和審計(jì)方法,統(tǒng)一的調(diào)度方式,統(tǒng)一的訪問入口等等。
微服務(wù)的目的是有效的拆分應(yīng)用,實(shí)現(xiàn)敏捷開發(fā)和部署 。
微服務(wù)提倡的理念團(tuán)隊(duì)間應(yīng)該是 inter-operate, not integrate 。inter-operate是定義好系統(tǒng)的邊界和接口,在一個(gè)團(tuán)隊(duì)內(nèi)全棧,讓團(tuán)隊(duì)自治,原因就是因?yàn)槿绻麍F(tuán)隊(duì)按照這樣的方式組建,將溝通的成本維持在系統(tǒng)內(nèi)部,每個(gè)子系統(tǒng)就會(huì)更加內(nèi)聚,彼此的依賴耦合能變?nèi)酰缦到y(tǒng)的溝通成本也就能降低。
5. 什么樣的項(xiàng)目適合微服務(wù)
微服務(wù)可以按照業(yè)務(wù)功能本身的獨(dú)立性來(lái)劃分,如果系統(tǒng)提供的業(yè)務(wù)是非常底層的,如:操作系統(tǒng)內(nèi)核、存儲(chǔ)系統(tǒng)、網(wǎng)絡(luò)系統(tǒng)、數(shù)據(jù)庫(kù)系統(tǒng)等等,這類系統(tǒng)都偏底層,功能和功能之間有著緊密的配合關(guān)系,如果強(qiáng)制拆分為較小的服務(wù)單元,會(huì)讓集成工作量急劇上升,并且這種人為的切割無(wú)法帶來(lái)業(yè)務(wù)上的真正的隔離,所以無(wú)法做到獨(dú)立部署和運(yùn)行,也就不適合做成微服務(wù)了。
能不能做成微服務(wù),取決于四個(gè)要素:
小:微服務(wù)體積小,2 pizza 團(tuán)隊(duì)。
獨(dú):能夠獨(dú)立的部署和運(yùn)行。
輕:使用輕量級(jí)的通信機(jī)制和架構(gòu)。
松:為服務(wù)之間是松耦合的。
6. 微服務(wù)折分與設(shè)計(jì)
從單體式結(jié)構(gòu)轉(zhuǎn)向微服務(wù)架構(gòu)中會(huì)持續(xù)碰到服務(wù)邊界劃分的問題:比如,我們有user 服務(wù)來(lái)提供用戶的基礎(chǔ)信息,那么用戶的頭像和圖片等是應(yīng)該單獨(dú)劃分為一個(gè)新的service更好還是應(yīng)該合并到user服務(wù)里呢?如果服務(wù)的粒度劃分的過粗,那就回到了單體式的老路;如果過細(xì),那服務(wù)間調(diào)用的開銷就變得不可忽視了,管理難度也會(huì)指數(shù)級(jí)增加。目前為止還沒有一個(gè)可以稱之為服務(wù)邊界劃分的標(biāo)準(zhǔn),只能根據(jù)不同的業(yè)務(wù)系統(tǒng)加以調(diào)節(jié)
拆分的大原則是當(dāng)一塊業(yè)務(wù)不依賴或極少依賴其它服務(wù),有獨(dú)立的業(yè)務(wù)語(yǔ)義,為超過2個(gè)的其他服務(wù)或客戶端提供數(shù)據(jù),那么它就應(yīng)該被拆分成一個(gè)獨(dú)立的服務(wù)模塊。
6.1 微服務(wù)設(shè)計(jì)原則
單一職責(zé)原則
意思是每個(gè)微服務(wù)只需要實(shí)現(xiàn)自己的業(yè)務(wù)邏輯就可以了,比如訂單管理模塊,它只需要處理訂單的業(yè)務(wù)邏輯就可以了,其它的不必考慮。
服務(wù)自治原則
意思是每個(gè)微服務(wù)從開發(fā)、測(cè)試、運(yùn)維等都是獨(dú)立的,包括存儲(chǔ)的數(shù)據(jù)庫(kù)也都是獨(dú)立的,自己就有一套完整的流程,我們完全可以把它當(dāng)成一個(gè)項(xiàng)目來(lái)對(duì)待。不必依賴于其它模塊。
輕量級(jí)通信原則
首先是通信的語(yǔ)言非常的輕量,第二,該通信方式需要是跨語(yǔ)言、跨平臺(tái)的,之所以要跨平臺(tái)、跨語(yǔ)言就是為了讓每個(gè)微服務(wù)都有足夠的獨(dú)立性,可以不受技術(shù)的鉗制。
接口明確原則
由于微服務(wù)之間可能存在著調(diào)用關(guān)系,為了盡量避免以后由于某個(gè)微服務(wù)的接口變化而導(dǎo)致其它微服務(wù)都做調(diào)整,在設(shè)計(jì)之初就要考慮到所有情況,讓接口盡量做的更通用,更靈活,從而盡量避免其它模塊也做調(diào)整。
7. 微服務(wù)優(yōu)勢(shì)與缺點(diǎn)
7.1 特性
每個(gè)微服務(wù)可獨(dú)立運(yùn)行在自己的進(jìn)程里;
一系列獨(dú)立運(yùn)行的微服務(wù)共同構(gòu)建起了整個(gè)系統(tǒng);
每個(gè)服務(wù)為獨(dú)立的業(yè)務(wù)開發(fā),一個(gè)微服務(wù)一般完成某個(gè)特定的功能,比如:訂單管理,用戶管理等;
微服務(wù)之間通過一些輕量級(jí)的通信機(jī)制進(jìn)行通信,例如通過REST API或者RPC的方式進(jìn)行調(diào)用。
7.2 特點(diǎn)
易于開發(fā)和維護(hù)
由于微服務(wù)單個(gè)模塊就相當(dāng)于一個(gè)項(xiàng)目,開發(fā)這個(gè)模塊我們就只需關(guān)心這個(gè)模塊的邏輯即可,代碼量和邏輯復(fù)雜度都會(huì)降低,從而易于開發(fā)和維護(hù)。
啟動(dòng)較快
這是相對(duì)單個(gè)微服務(wù)來(lái)講的,相比于啟動(dòng)單體架構(gòu)的整個(gè)項(xiàng)目,啟動(dòng)某個(gè)模塊的服務(wù)速度明顯是要快很多的。
局部修改容易部署
在開發(fā)中發(fā)現(xiàn)了一個(gè)問題,如果是單體架構(gòu)的話,我們就需要重新發(fā)布并啟動(dòng)整個(gè)項(xiàng)目,非常耗時(shí)間,但是微服務(wù)則不同,哪個(gè)模塊出現(xiàn)了bug我們只需要解決那個(gè)模塊的bug就可以了,解決完bug之后,我們只需要重啟這個(gè)模塊的服務(wù)即可,部署相對(duì)簡(jiǎn)單,不必重啟整個(gè)項(xiàng)目從而大大節(jié)約時(shí)間。
技術(shù)棧不受限
比如訂單微服務(wù)和電影微服務(wù)原來(lái)都是用java寫的,現(xiàn)在我們想把電影微服務(wù)改成nodeJs技術(shù),這是完全可以的,而且由于所關(guān)注的只是電影的邏輯而已,因此技術(shù)更換的成本也就會(huì)少很多。
按需伸縮
我們上面說(shuō)了單體架構(gòu)在想擴(kuò)展某個(gè)模塊的性能時(shí)不得不考慮到其它模塊的性能會(huì)不會(huì)受影響,對(duì)于我們微服務(wù)來(lái)講,完全不是問題,電影模塊通過什么方式來(lái)提升性能不必考慮其它模塊的情況。
7.3 缺點(diǎn)
運(yùn)維要求較高
對(duì)于單體架構(gòu)來(lái)講,我們只需要維護(hù)好這一個(gè)項(xiàng)目就可以了,但是對(duì)于微服務(wù)架構(gòu)來(lái)講,由于項(xiàng)目是由多個(gè)微服務(wù)構(gòu)成的,每個(gè)模塊出現(xiàn)問題都會(huì)造成整個(gè)項(xiàng)目運(yùn)行出現(xiàn)異常,想要知道是哪個(gè)模塊造成的問題往往是不容易的,因?yàn)槲覀儫o(wú)法一步一步通過debug的方式來(lái)跟蹤,這就對(duì)運(yùn)維人員提出了很高的要求。
分布式的復(fù)雜性
對(duì)于單體架構(gòu)來(lái)講,我們可以不使用分布式,但是對(duì)于微服務(wù)架構(gòu)來(lái)說(shuō),分布式幾乎是必會(huì)用的技術(shù),由于分布式本身的復(fù)雜性,導(dǎo)致微服務(wù)架構(gòu)也變得復(fù)雜起來(lái)。
接口調(diào)整成本高
比如,用戶微服務(wù)是要被訂單微服務(wù)和電影微服務(wù)所調(diào)用的,一旦用戶微服務(wù)的接口發(fā)生大的變動(dòng),那么所有依賴它的微服務(wù)都要做相應(yīng)的調(diào)整,由于微服務(wù)可能非常多,那么調(diào)整接口所造成的成本將會(huì)明顯提高。
重復(fù)勞動(dòng)
對(duì)于單體架構(gòu)來(lái)講,如果某段業(yè)務(wù)被多個(gè)模塊所共同使用,我們便可以抽象成一個(gè)工具類,被所有模塊直接調(diào)用,但是微服務(wù)卻無(wú)法這樣做,因?yàn)檫@個(gè)微服務(wù)的工具類是不能被其它微服務(wù)所直接調(diào)用的,從而我們便不得不在每個(gè)微服務(wù)上都建這么一個(gè)工具類,從而導(dǎo)致代碼的重復(fù)。
8. 微服務(wù)開發(fā)框架
目前微服務(wù)的開發(fā)框架,最常用的有以下四個(gè):
Spring Cloud:http://projects.spring.io/spring-cloud(現(xiàn)在非常流行的微服務(wù)架構(gòu))
Dubbo:http://dubbo.io
Dropwizard:http://www.dropwizard.io (關(guān)注單個(gè)微服務(wù)的開發(fā))
Consul、etcd&etc.(微服務(wù)的模塊)
9. Sprint cloud 和 Sprint boot區(qū)別
Spring Boot:
旨在簡(jiǎn)化創(chuàng)建產(chǎn)品級(jí)的Spring應(yīng)用和服務(wù),簡(jiǎn)化了配置文件,使用嵌入式web服務(wù)器,含有諸多開箱即用微服務(wù)功能,可以和spring cloud聯(lián)合部署。
Spring Cloud:
微服務(wù)工具包,為開發(fā)者提供了在分布式系統(tǒng)的配置管理、服務(wù)發(fā)現(xiàn)、斷路器、智能路由、微代理、控制總線等開發(fā)工具包。
二、微服務(wù)實(shí)踐先知
1. 客戶端如何訪問這些服務(wù)?(API Gateway)
傳統(tǒng)的開發(fā)方式,所有的服務(wù)都是本地的,UI可以直接調(diào)用,現(xiàn)在按功能拆分成獨(dú)立的服務(wù),跑在獨(dú)立的一般都在獨(dú)立的虛擬機(jī)上的 Java進(jìn)程了。客戶端UI如何訪問他的?后臺(tái)有N個(gè)服務(wù),前臺(tái)就需要記住管理N個(gè)服務(wù),一個(gè)服務(wù)下線/更新/升級(jí),前臺(tái)就要重新部署,這明顯不服務(wù)我們 拆分的理念,特別當(dāng)前臺(tái)是移動(dòng)應(yīng)用的時(shí)候,通常業(yè)務(wù)變化的節(jié)奏更快。另外,N個(gè)小服務(wù)的調(diào)用也是一個(gè)不小的網(wǎng)絡(luò)開銷。還有一般微服務(wù)在系統(tǒng)內(nèi)部,通常是無(wú)狀態(tài)的,用戶登錄信息和權(quán)限管理最好有一個(gè)統(tǒng)一的地方維護(hù)管理(OAuth)。
所以,一般在后臺(tái)N個(gè)服務(wù)和UI之間一般會(huì)一個(gè)代理或者叫API Gateway,他的作用包括
提供統(tǒng)一服務(wù)入口,讓微服務(wù)對(duì)前臺(tái)透明
聚合后臺(tái)的服務(wù),節(jié)省流量,提升性能
提供安全,過濾,流控等API管理功能
我的理解其實(shí)這個(gè)API Gateway可以有很多廣義的實(shí)現(xiàn)辦法,可以是一個(gè)軟硬一體的盒子,也可以是一個(gè)簡(jiǎn)單的MVC框架,甚至是一個(gè)Node.js的服務(wù)端。他們最重要的作用是為前臺(tái)(通常是移動(dòng)應(yīng)用)提供后臺(tái)服務(wù)的聚合,提供一個(gè)統(tǒng)一的服務(wù)出口,解除他們之間的耦合,不過API Gateway也有可能成為單點(diǎn)故障點(diǎn)或者性能的瓶頸。
2. 服務(wù)之間如何通信?(服務(wù)調(diào)用)
因?yàn)樗械奈⒎?wù)都是獨(dú)立的Java進(jìn)程跑在獨(dú)立的虛擬機(jī)上,所以服務(wù)間的通行就是IPC(inter process communication),已經(jīng)有很多成熟的方案。現(xiàn)在基本最通用的有兩種方式。這幾種方式,展開來(lái)講都可以寫本書,而且大家一般都比較熟悉細(xì)節(jié)了, 就不展開講了。
REST(JAX-RS,Spring Boot)
RPC(Thrift, Dubbo)
異步消息調(diào)用(Kafka, Notify)
一般同步調(diào)用比較簡(jiǎn)單,一致性強(qiáng),但是容易出調(diào)用問題,性能體驗(yàn)上也會(huì)差些,特別是調(diào)用層次多的時(shí)候。RESTful和RPC的比較也是一個(gè)很有意 思的話題。一般REST基于HTTP,更容易實(shí)現(xiàn),更容易被接受,服務(wù)端實(shí)現(xiàn)技術(shù)也更靈活些,各個(gè)語(yǔ)言都能支持,同時(shí)能跨客戶端,對(duì)客戶端沒有特殊的要 求,只要封裝了HTTP的SDK就能調(diào)用,所以相對(duì)使用的廣一些。RPC也有自己的優(yōu)點(diǎn),傳輸協(xié)議更高效,安全更可控,特別在一個(gè)公司內(nèi)部,如果有統(tǒng)一個(gè)的開發(fā)規(guī)范和統(tǒng)一的服務(wù)框架時(shí),他的開發(fā)效率優(yōu)勢(shì)更明顯些。就看各自的技術(shù)積累實(shí)際條件,自己的選擇了。
而異步消息的方式在分布式系統(tǒng)中有特別廣泛的應(yīng)用,他既能減低調(diào)用服務(wù)之間的耦合,又能成為調(diào)用之間的緩沖,確保消息積壓不會(huì)沖垮被調(diào)用方,同時(shí)能 保證調(diào)用方的服務(wù)體驗(yàn),繼續(xù)干自己該干的活,不至于被后臺(tái)性能拖慢。不過需要付出的代價(jià)是一致性的減弱,需要接受數(shù)據(jù)最終一致性;還有就是后臺(tái)服務(wù)一般要 實(shí)現(xiàn)冪等性,因?yàn)橄l(fā)送出于性能的考慮一般會(huì)有重復(fù)(保證消息的被收到且僅收到一次對(duì)性能是很大的考驗(yàn));最后就是必須引入一個(gè)獨(dú)立的broker,如 果公司內(nèi)部沒有技術(shù)積累,對(duì)broker分布式管理也是一個(gè)很大的挑戰(zhàn)。
3. 這么多服務(wù)怎么查找?(服務(wù)發(fā)現(xiàn))
在微服務(wù)架構(gòu)中,一般每一個(gè)服務(wù)都是有多個(gè)拷貝,來(lái)做負(fù)載均衡。一個(gè)服務(wù)隨時(shí)可能下線,也可能應(yīng)對(duì)臨時(shí)訪問壓力增加新的服務(wù)節(jié)點(diǎn)。服務(wù)之間如何相互 感知?服務(wù)如何管理?這就是服務(wù)發(fā)現(xiàn)的問題了。一般有兩類做法,也各有優(yōu)缺點(diǎn)。基本都是通過zookeeper等類似技術(shù)做服務(wù)注冊(cè)信息的分布式管理。當(dāng) 服務(wù)上線時(shí),服務(wù)提供者將自己的服務(wù)信息注冊(cè)到ZK(或類似框架),并通過心跳維持長(zhǎng)鏈接,實(shí)時(shí)更新鏈接信息。服務(wù)調(diào)用者通過ZK尋址,根據(jù)可定制算法,找到一個(gè)服務(wù),還可以將服務(wù)信息緩存在本地以提高性能。當(dāng)服務(wù)下線時(shí),ZK會(huì)發(fā)通知給服務(wù)客戶端。
客戶端做:優(yōu)點(diǎn)是架構(gòu)簡(jiǎn)單,擴(kuò)展靈活,只對(duì)服務(wù)注冊(cè)器依賴。缺點(diǎn)是客戶端要維護(hù)所有調(diào)用服務(wù)的地址,有技術(shù)難度,一般大公司都有成熟的內(nèi)部框架支持,比如Dubbo。
服務(wù)端做:優(yōu)點(diǎn)是簡(jiǎn)單,所有服務(wù)對(duì)于前臺(tái)調(diào)用方透明,一般在小公司在云服務(wù)上部署的應(yīng)用采用的比較多。
4. 服務(wù)掛了怎么辦?
分布式最大的特性就是網(wǎng)絡(luò)是不可靠 的。通過微服務(wù)拆分能降低這個(gè)風(fēng)險(xiǎn),不過如果沒有特別的保障,結(jié)局肯定是噩夢(mèng)。我們剛遇到一個(gè)線上故障就是一個(gè)很不起眼的SQL計(jì)數(shù)功能,在訪問量上升 時(shí),導(dǎo)致數(shù)據(jù)庫(kù)load彪高,影響了所在應(yīng)用的性能,從而影響所有調(diào)用這個(gè)應(yīng)用服務(wù)的前臺(tái)應(yīng)用。所以當(dāng)我們的系統(tǒng)是由一系列的服務(wù)調(diào)用鏈組成的時(shí)候,我們必須確保任一環(huán)節(jié)出問題都不至于影響整體鏈路。相應(yīng)的手段有很多:
重試機(jī)制
限流
熔斷機(jī)制
負(fù)載均衡
降級(jí)(本地緩存) 這些方法基本上都很明確通用,就不詳細(xì)說(shuō)明了。比如Netflix的Hystrix:https://github.com/Netflix/Hystrix
5. 微服務(wù)需要考慮的問題
這里有一個(gè)圖非常好的總結(jié)微服務(wù)架構(gòu)需要考慮的問題,包括
API Gateway
服務(wù)間調(diào)用
服務(wù)發(fā)現(xiàn)
服務(wù)容錯(cuò)
服務(wù)部署
數(shù)據(jù)調(diào)用
三、微服務(wù)重要部件
1. 微服務(wù)基本能力
2. 服務(wù)注冊(cè)中心
服務(wù)之間需要?jiǎng)?chuàng)建一種服務(wù)發(fā)現(xiàn)機(jī)制,用于幫助服務(wù)之間互相感知彼此的存在。服務(wù)啟動(dòng)時(shí)會(huì)將自身的服務(wù)信息注冊(cè)到注冊(cè)中心,并訂閱自己需要消費(fèi)的服務(wù)。
服務(wù)注冊(cè)中心是服務(wù)發(fā)現(xiàn)的核心。它保存了各個(gè)可用服務(wù)實(shí)例的網(wǎng)絡(luò)地址(IPAddress和Port)。服務(wù)注冊(cè)中心必須要有高可用性和實(shí)時(shí)更新功能。上面提到的 Netflix Eureka 就是一個(gè)服務(wù)注冊(cè)中心。它提供了服務(wù)注冊(cè)和查詢服務(wù)信息的REST API。服務(wù)通過使用POST請(qǐng)求注冊(cè)自己的IPAddress和Port。每30秒發(fā)送一個(gè)PUT請(qǐng)求刷新注冊(cè)信息。通過DELETE請(qǐng)求注銷服務(wù)。客戶端通過GET請(qǐng)求獲取可用的服務(wù)實(shí)例信息。 Netflix的高可用(Netflix achieves high availability )是通過在Amazon EC2運(yùn)行多個(gè)實(shí)例來(lái)實(shí)現(xiàn)的,每一個(gè)Eureka服務(wù)都有一個(gè)彈性IP Address。當(dāng)Eureka服務(wù)啟動(dòng)時(shí),有DNS服務(wù)器動(dòng)態(tài)的分配。Eureka客戶端通過查詢 DNS來(lái)獲取Eureka的網(wǎng)絡(luò)地址(IP Address和Port)。一般情況下,都是返回和客戶端在同一個(gè)可用區(qū)Eureka服務(wù)器地址。 其他能夠作為服務(wù)注冊(cè)中心的有:
etcd —– 高可用,分布式,強(qiáng)一致性的,key-value,Kubernetes和Cloud Foundry都是使用了etcd。
consul —–一個(gè)用于discovering和configuring的工具。它提供了允許客戶端注冊(cè)和發(fā)現(xiàn)服務(wù)的API。Consul可以進(jìn)行服務(wù)健康檢查,以確定服務(wù)的可用性。
zookeeper —— 在分布式應(yīng)用中被廣泛使用,高性能的協(xié)調(diào)服務(wù)。 Apache Zookeeper 最初為Hadoop的一個(gè)子項(xiàng)目,但現(xiàn)在是一個(gè)頂級(jí)項(xiàng)目。
2.1 zookeeper服務(wù)注冊(cè)和發(fā)現(xiàn)
簡(jiǎn)單來(lái)講,zookeeper可以充當(dāng)一個(gè)服務(wù)注冊(cè)表(Service Registry),讓多個(gè)服務(wù)提供者形成一個(gè)集群,讓服務(wù)消費(fèi)者通過服務(wù)注冊(cè)表獲取具體的服務(wù)訪問地址(ip+端口)去訪問具體的服務(wù)提供者。如下圖所示:
具體來(lái)說(shuō),zookeeper就是個(gè)分布式文件系統(tǒng),每當(dāng)一個(gè)服務(wù)提供者部署后都要將自己的服務(wù)注冊(cè)到zookeeper的某一路徑上: /{service}/{version}/{ip:port}, 比如我們的HelloWorldService部署到兩臺(tái)機(jī)器,那么zookeeper上就會(huì)創(chuàng)建兩條目錄:分別為/HelloWorldService/1.0.0/100.19.20.01:16888 /HelloWorldService/1.0.0/100.19.20.02:16888。
zookeeper提供了“心跳檢測(cè)”功能,它會(huì)定時(shí)向各個(gè)服務(wù)提供者發(fā)送一個(gè)請(qǐng)求(實(shí)際上建立的是一個(gè) socket 長(zhǎng)連接),如果長(zhǎng)期沒有響應(yīng),服務(wù)中心就認(rèn)為該服務(wù)提供者已經(jīng)“掛了”,并將其剔除,比如100.19.20.02這臺(tái)機(jī)器如果宕機(jī)了,那么zookeeper上的路徑就會(huì)只剩/HelloWorldService/1.0.0/100.19.20.01:16888。
服務(wù)消費(fèi)者會(huì)去監(jiān)聽相應(yīng)路徑(/HelloWorldService/1.0.0),一旦路徑上的數(shù)據(jù)有任務(wù)變化(增加或減少),zookeeper都會(huì)通知服務(wù)消費(fèi)方服務(wù)提供者地址列表已經(jīng)發(fā)生改變,從而進(jìn)行更新。
更為重要的是zookeeper 與生俱來(lái)的容錯(cuò)容災(zāi)能力(比如leader選舉),可以確保服務(wù)注冊(cè)表的高可用性。
3. 負(fù)載均衡
服務(wù)高可用的保證手段,為了保證高可用,每一個(gè)微服務(wù)都需要部署多個(gè)服務(wù)實(shí)例來(lái)提供服務(wù)。此時(shí)客戶端進(jìn)行服務(wù)的負(fù)載均衡。
3.1 負(fù)載均衡的常見策略
3.1.1 隨機(jī)
把來(lái)自網(wǎng)絡(luò)的請(qǐng)求隨機(jī)分配給內(nèi)部中的多個(gè)服務(wù)器。
3.1.2 輪詢
每一個(gè)來(lái)自網(wǎng)絡(luò)中的請(qǐng)求,輪流分配給內(nèi)部的服務(wù)器,從1到N然后重新開始。此種負(fù)載均衡算法適合服務(wù)器組內(nèi)部的服務(wù)器都具有相同的配置并且平均服務(wù)請(qǐng)求相對(duì)均衡的情況。
3.1.3 加權(quán)輪詢
根據(jù)服務(wù)器的不同處理能力,給每個(gè)服務(wù)器分配不同的權(quán)值,使其能夠接受相應(yīng)權(quán)值數(shù)的服務(wù)請(qǐng)求。例如:服務(wù)器A的權(quán)值被設(shè)計(jì)成1,B的權(quán)值是3,C的權(quán)值是6,則服務(wù)器A、B、C將分別接受到10%、30%、60%的服務(wù)請(qǐng)求。此種均衡算法能確保高性能的服務(wù)器得到更多的使用率,避免低性能的服務(wù)器負(fù)載過重。
3.1.4 IP Hash
這種方式通過生成請(qǐng)求源IP的哈希值,并通過這個(gè)哈希值來(lái)找到正確的真實(shí)服務(wù)器。這意味著對(duì)于同一主機(jī)來(lái)說(shuō)他對(duì)應(yīng)的服務(wù)器總是相同。使用這種方式,你不需要保存任何源IP。但是需要注意,這種方式可能導(dǎo)致服務(wù)器負(fù)載不平衡。
3.1.5 最少連接數(shù)
客戶端的每一次請(qǐng)求服務(wù)在服務(wù)器停留的時(shí)間可能會(huì)有較大的差異,隨著工作時(shí)間加長(zhǎng),如果采用簡(jiǎn)單的輪循或隨機(jī)均衡算法,每一臺(tái)服務(wù)器上的連接進(jìn)程可能會(huì)產(chǎn)生極大的不同,并沒有達(dá)到真正的負(fù)載均衡。最少連接數(shù)均衡算法對(duì)內(nèi)部中需負(fù)載的每一臺(tái)服務(wù)器都有一個(gè)數(shù)據(jù)記錄,記錄當(dāng)前該服務(wù)器正在處理的連接數(shù)量,當(dāng)有新的服務(wù)連接請(qǐng)求時(shí),將把當(dāng)前請(qǐng)求分配給連接數(shù)最少的服務(wù)器,使均衡更加符合實(shí)際情況,負(fù)載更加均衡。此種均衡算法適合長(zhǎng)時(shí)處理的請(qǐng)求服務(wù),如FTP。
4. 容錯(cuò)
容錯(cuò),這個(gè)詞的理解,直面意思就是可以容下錯(cuò)誤,不讓錯(cuò)誤再次擴(kuò)張,讓這個(gè)錯(cuò)誤產(chǎn)生的影響在一個(gè)固定的邊界之內(nèi),“千里之堤毀于蟻穴”我們用容錯(cuò)的方式就是讓這種蟻穴不要變大。那么我們常見的降級(jí),限流,熔斷器,超時(shí)重試等等都是容錯(cuò)的方法。
在調(diào)用服務(wù)集群時(shí),如果一個(gè)微服務(wù)調(diào)用異常,如超時(shí),連接異常,網(wǎng)絡(luò)異常等,則根據(jù)容錯(cuò)策略進(jìn)行服務(wù)容錯(cuò)。目前支持的服務(wù)容錯(cuò)策略有快速失敗,失效切換。如果連續(xù)失敗多次則直接熔斷,不再發(fā)起調(diào)用。這樣可以避免一個(gè)服務(wù)異常拖垮所有依賴于他的服務(wù)。
4.1 容錯(cuò)策略
4.1.1 快速失敗
服務(wù)只發(fā)起一次待用,失敗立即報(bào)錯(cuò)。通常用于非冪等下性的寫操作
4.1.2 失效切換
服務(wù)發(fā)起調(diào)用,當(dāng)出現(xiàn)失敗后,重試其他服務(wù)器。通常用于讀操作,但重試會(huì)帶來(lái)更長(zhǎng)時(shí)間的延遲。重試的次數(shù)通常是可以設(shè)置的
4.1.3 失敗安全
失敗安全, 當(dāng)服務(wù)調(diào)用出現(xiàn)異常時(shí),直接忽略。通常用于寫入日志等操作。
4.1.4 失敗自動(dòng)恢復(fù)
當(dāng)服務(wù)調(diào)用出現(xiàn)異常時(shí),記錄失敗請(qǐng)求,定時(shí)重發(fā)。通常用于消息通知。
4.1.5 forking Cluster
并行調(diào)用多個(gè)服務(wù)器,只要有一個(gè)成功,即返回。通常用于實(shí)時(shí)性較高的讀操作。可以通過forks=n來(lái)設(shè)置最大并行數(shù)。
4.1.6 廣播調(diào)用
廣播調(diào)用所有提供者,逐個(gè)調(diào)用,任何一臺(tái)失敗則失敗。通常用于通知所有提供者更新緩存或日志等本地資源信息。
5. 熔斷
熔斷技術(shù)可以說(shuō)是一種“智能化的容錯(cuò)”,當(dāng)調(diào)用滿足失敗次數(shù),失敗比例就會(huì)觸發(fā)熔斷器打開,有程序自動(dòng)切斷當(dāng)前的RPC調(diào)用,來(lái)防止錯(cuò)誤進(jìn)一步擴(kuò)大。實(shí)現(xiàn)一個(gè)熔斷器主要是考慮三種模式,關(guān)閉,打開,半開。各個(gè)狀態(tài)的轉(zhuǎn)換如下圖。
我們?cè)谔幚懋惓5臅r(shí)候,要根據(jù)具體的業(yè)務(wù)情況來(lái)決定處理方式,比如我們調(diào)用商品接口,對(duì)方只是臨時(shí)做了降級(jí)處理,那么作為網(wǎng)關(guān)調(diào)用就要切到可替換的服務(wù)上來(lái)執(zhí)行或者獲取托底數(shù)據(jù),給用戶友好提示。還有要區(qū)分異常的類型,比如依賴的服務(wù)崩潰了,這個(gè)可能需要花費(fèi)比較久的時(shí)間來(lái)解決。也可能是由于服務(wù)器負(fù)載臨時(shí)過高導(dǎo)致超時(shí)。作為熔斷器應(yīng)該能夠甄別這種異常類型,從而根據(jù)具體的錯(cuò)誤類型調(diào)整熔斷策略。增加手動(dòng)設(shè)置,在失敗的服務(wù)恢復(fù)時(shí)間不確定的情況下,管理員可以手動(dòng)強(qiáng)制切換熔斷狀態(tài)。最后,熔斷器的使用場(chǎng)景是調(diào)用可能失敗的遠(yuǎn)程服務(wù)程序或者共享資源。如果是本地緩存本地私有資源,使用熔斷器則會(huì)增加系統(tǒng)的額外開銷。還要注意,熔斷器不能作為應(yīng)用程序中業(yè)務(wù)邏輯的異常處理替代品。
有一些異常比較頑固,突然發(fā)生,無(wú)法預(yù)測(cè),而且很難恢復(fù),并且還會(huì)導(dǎo)致級(jí)聯(lián)失敗(舉個(gè)例子,假設(shè)一個(gè)服務(wù)集群的負(fù)載非常高,如果這時(shí)候集群的一部分掛掉了,還占了很大一部分資源,整個(gè)集群都有可能遭殃)。如果我們這時(shí)還是不斷進(jìn)行重試的話,結(jié)果大多都是失敗的。因此,此時(shí)我們的應(yīng)用需要立即進(jìn)入失敗狀態(tài)(fast-fail),并采取合適的方法進(jìn)行恢復(fù)。
我們可以用狀態(tài)機(jī)來(lái)實(shí)現(xiàn)CircuitBreaker,它有以下三種狀態(tài):
關(guān)閉( Closed ):默認(rèn)情況下Circuit Breaker是關(guān)閉的,此時(shí)允許操作執(zhí)行。CircuitBreaker內(nèi)部記錄著最近失敗的次數(shù),如果對(duì)應(yīng)的操作執(zhí)行失敗,次數(shù)就會(huì)續(xù)一次。如果在某個(gè)時(shí)間段內(nèi),失敗次數(shù)(或者失敗比率)達(dá)到閾值,CircuitBreaker會(huì)轉(zhuǎn)換到開啟( Open )狀態(tài)。在開啟狀態(tài)中,Circuit Breaker會(huì)啟用一個(gè)超時(shí)計(jì)時(shí)器,設(shè)這個(gè)計(jì)時(shí)器的目的是給集群相應(yīng)的時(shí)間來(lái)恢復(fù)故障。當(dāng)計(jì)時(shí)器時(shí)間到的時(shí)候,CircuitBreaker會(huì)轉(zhuǎn)換到半開啟( Half-Open )狀態(tài)。
開啟( Open ):在此狀態(tài)下,執(zhí)行對(duì)應(yīng)的操作將會(huì)立即失敗并且立即拋出異常。
半開啟( Half-Open ):在此狀態(tài)下,Circuit Breaker會(huì)允許執(zhí)行一定數(shù)量的操作。如果所有操作全部成功,CircuitBreaker就會(huì)假定故障已經(jīng)恢復(fù),它就會(huì)轉(zhuǎn)換到關(guān)閉狀態(tài),并且重置失敗次數(shù)。如果其中 任意一次 操作失敗了,Circuit Breaker就會(huì)認(rèn)為故障仍然存在,所以它會(huì)轉(zhuǎn)換到開啟狀態(tài)并再次開啟計(jì)時(shí)器(再給系統(tǒng)一些時(shí)間使其從失敗中恢復(fù))
6. 限流和降級(jí)
保證核心服務(wù)的穩(wěn)定性。為了保證核心服務(wù)的穩(wěn)定性,隨著訪問量的不斷增加,需要為系統(tǒng)能夠處理的服務(wù)數(shù)量設(shè)置一個(gè)極限閥值,超過這個(gè)閥值的請(qǐng)求則直接拒絕。同時(shí),為了保證核心服務(wù)的可用,可以對(duì)否些非核心服務(wù)進(jìn)行降級(jí),通過限制服務(wù)的最大訪問量進(jìn)行限流,通過管理控制臺(tái)對(duì)單個(gè)微服務(wù)進(jìn)行人工降級(jí)
7. SLA
SLA:Service-LevelAgreement的縮寫,意思是服務(wù)等級(jí)協(xié)議。 是關(guān)于網(wǎng)絡(luò)服務(wù)供應(yīng)商和客戶間的一份合同,其中定義了服務(wù)類型、服務(wù)質(zhì)量和客戶付款等術(shù)語(yǔ)。 典型的SLA包括以下項(xiàng)目:
分配給客戶的最小帶寬;
客戶帶寬極限;
能同時(shí)服務(wù)的客戶數(shù)目;
在可能影響用戶行為的網(wǎng)絡(luò)變化之前的通知安排;
撥入訪問可用性;
運(yùn)用統(tǒng)計(jì)學(xué);
服務(wù)供應(yīng)商支持的最小網(wǎng)絡(luò)利用性能,如99.9%有效工作時(shí)間或每天最多為1分鐘的停機(jī)時(shí)間;
各類客戶的流量?jī)?yōu)先權(quán);
客戶技術(shù)支持和服務(wù);
懲罰規(guī)定,為服務(wù)供應(yīng)商不能滿足 SLA需求所指定。
8. API網(wǎng)關(guān)
這里說(shuō)的網(wǎng)關(guān)是指API網(wǎng)關(guān),直面意思是將所有API調(diào)用統(tǒng)一接入到API網(wǎng)關(guān)層,有網(wǎng)關(guān)層統(tǒng)一接入和輸出。一個(gè)網(wǎng)關(guān)的基本功能有:統(tǒng)一接入、安全防護(hù)、協(xié)議適配、流量管控、長(zhǎng)短鏈接支持、容錯(cuò)能力。有了網(wǎng)關(guān)之后,各個(gè)API服務(wù)提供團(tuán)隊(duì)可以專注于自己的的業(yè)務(wù)邏輯處理,而API網(wǎng)關(guān)更專注于安全、流量、路由等問題。
9. 多級(jí)緩存
最簡(jiǎn)單的緩存就是查一次數(shù)據(jù)庫(kù)然后將數(shù)據(jù)寫入緩存比如redis中并設(shè)置過期時(shí)間。因?yàn)橛羞^期失效因此我們要關(guān)注下緩存的穿透率,這個(gè)穿透率的計(jì)算公式,比如查詢方法queryOrder(調(diào)用次數(shù)1000/1s)里面嵌套查詢DB方法queryProductFromDb(調(diào)用次數(shù)300/s),那么redis的穿透率就是300/1000,在這種使用緩存的方式下,是要重視穿透率的,穿透率大了說(shuō)明緩存的效果不好。還有一種使用緩存的方式就是將緩存持久化,也就是不設(shè)置過期時(shí)間,這個(gè)就會(huì)面臨一個(gè)數(shù)據(jù)更新的問題。一般有兩種辦法,一個(gè)是利用時(shí)間戳,查詢默認(rèn)以redis為主,每次設(shè)置數(shù)據(jù)的時(shí)候放入一個(gè)時(shí)間戳,每次讀取數(shù)據(jù)的時(shí)候用系統(tǒng)當(dāng)前時(shí)間和上次設(shè)置的這個(gè)時(shí)間戳做對(duì)比,比如超過5分鐘,那么就再查一次數(shù)據(jù)庫(kù)。這樣可以保證redis里面永遠(yuǎn)有數(shù)據(jù),一般是對(duì)DB的一種容錯(cuò)方法。還有一個(gè)就是真正的讓redis做為DB使用。就是圖里面畫的通過訂閱數(shù)據(jù)庫(kù)的binlog通過數(shù)據(jù)異構(gòu)系統(tǒng)將數(shù)據(jù)推送給緩存,同時(shí)將將緩存設(shè)置為多級(jí)。可以通過使用jvmcache作為應(yīng)用內(nèi)的一級(jí)緩存,一般是體積小,訪問頻率大的更適合這種jvmcache方式,將一套redis作為二級(jí)remote緩存,另外最外層三級(jí)redis作為持久化緩存。
10. 超時(shí)和重試
超時(shí)與重試機(jī)制也是容錯(cuò)的一種方法,凡是發(fā)生RPC調(diào)用的地方,比如讀取redis,db,mq等,因?yàn)榫W(wǎng)絡(luò)故障或者是所依賴的服務(wù)故障,長(zhǎng)時(shí)間不能返回結(jié)果,就會(huì)導(dǎo)致線程增加,加大cpu負(fù)載,甚至導(dǎo)致雪崩。所以對(duì)每一個(gè)RPC調(diào)用都要設(shè)置超時(shí)時(shí)間。對(duì)于強(qiáng)依賴RPC調(diào)用資源的情況,還要有重試機(jī)制,但是重試的次數(shù)建議1-2次,另外如果有重試,那么超時(shí)時(shí)間就要相應(yīng)的調(diào)小,比如重試1次,那么一共是發(fā)生2次調(diào)用。如果超時(shí)時(shí)間配置的是2s,那么客戶端就要等待4s才能返回。因此重試+超時(shí)的方式,超時(shí)時(shí)間要調(diào)小。這里也再談一下一次PRC調(diào)用的時(shí)間都消耗在哪些環(huán)節(jié),一次正常的調(diào)用統(tǒng)計(jì)的耗時(shí)主要包括: ①調(diào)用端RPC框架執(zhí)行時(shí)間 + ②網(wǎng)絡(luò)發(fā)送時(shí)間 + ③服務(wù)端RPC框架執(zhí)行時(shí)間 + ④服務(wù)端業(yè)務(wù)代碼時(shí)間。調(diào)用方和服務(wù)方都有各自的性能監(jiān)控,比如調(diào)用方tp99是500ms,服務(wù)方tp99是100ms,找了網(wǎng)絡(luò)組的同事確認(rèn)網(wǎng)絡(luò)沒有問題。那么時(shí)間都花在什么地方了呢,兩種原因,客戶端調(diào)用方,還有一個(gè)原因是網(wǎng)絡(luò)發(fā)生TCP重傳。所以要注意這兩點(diǎn)。
11. 線程池隔離
在抗量這個(gè)環(huán)節(jié),Servlet3異步的時(shí)候,有提到過線程隔離。線程隔離的之間優(yōu)勢(shì)就是防止級(jí)聯(lián)故障,甚至是雪崩。當(dāng)網(wǎng)關(guān)調(diào)用N多個(gè)接口服務(wù)的時(shí)候,我們要對(duì)每個(gè)接口進(jìn)行線程隔離。比如,我們有調(diào)用訂單、商品、用戶。那么訂單的業(yè)務(wù)不能夠影響到商品和用戶的請(qǐng)求處理。如果不做線程隔離,當(dāng)訪問訂單服務(wù)出現(xiàn)網(wǎng)絡(luò)故障導(dǎo)致延時(shí),線程積壓最終導(dǎo)致整個(gè)服務(wù)CPU負(fù)載滿。就是我們說(shuō)的服務(wù)全部不可用了,有多少機(jī)器都會(huì)被此刻的請(qǐng)求塞滿。那么有了線程隔離就會(huì)使得我們的網(wǎng)關(guān)能保證局部問題不會(huì)影響全局。
12. 降級(jí)和限流
關(guān)于降級(jí)限流的方法業(yè)界都已經(jīng)有很成熟的方法了,比如FAILBACK機(jī)制,限流的方法令牌桶,漏桶,信號(hào)量等。這里談一下我們的一些經(jīng)驗(yàn),降級(jí)一般都是由統(tǒng)一配置中心的降級(jí)開關(guān)來(lái)實(shí)現(xiàn)的,那么當(dāng)有很多個(gè)接口來(lái)自同一個(gè)提供方,這個(gè)提供方的系統(tǒng)或這機(jī)器所在機(jī)房網(wǎng)絡(luò)出現(xiàn)了問題,我們就要有一個(gè)統(tǒng)一的降級(jí)開關(guān),不然就要一個(gè)接口一個(gè)接口的來(lái)降級(jí)。也就是要對(duì)業(yè)務(wù)類型有一個(gè)大閘刀。還有就是 降級(jí)切記暴力降級(jí),什么是暴力降級(jí)的,比如把論壇功能降調(diào),結(jié)果用戶顯示一個(gè)大白板,我們要實(shí)現(xiàn)緩存住一些數(shù)據(jù),也就是有托底數(shù)據(jù)。限流一般分為分布式限流和單機(jī)限流,如果實(shí)現(xiàn)分布式限流的話就要一個(gè)公共的后端存儲(chǔ)服務(wù)比如redis,在大nginx節(jié)點(diǎn)上利用lua讀取redis配置信息。我們現(xiàn)在的限流都是單機(jī)限流,并沒有實(shí)施分布式限流。
13. 網(wǎng)關(guān)監(jiān)控和統(tǒng)計(jì)
API網(wǎng)關(guān)是一個(gè)串行的調(diào)用,那么每一步發(fā)生的異常要記錄下來(lái),統(tǒng)一存儲(chǔ)到一個(gè)地方比如elasticserach中,便于后續(xù)對(duì)調(diào)用異常的分析。鑒于公司docker申請(qǐng)都是統(tǒng)一分配,而且分配之前docker上已經(jīng)存在3個(gè)agent了,不再允許增加。我們自己實(shí)現(xiàn)了一個(gè)agent程序,來(lái)負(fù)責(zé)采集服務(wù)器上面的日志輸出,然后發(fā)送到kafka集群,再消費(fèi)到elasticserach中,通過web查詢。現(xiàn)在做的追蹤功能還比較簡(jiǎn)單,這塊還需要繼續(xù)豐富。
-
微服務(wù)
+關(guān)注
關(guān)注
0文章
145瀏覽量
7683
發(fā)布評(píng)論請(qǐng)先 登錄
企業(yè)使用NVIDIA NeMo微服務(wù)構(gòu)建AI智能體平臺(tái)
微服務(wù)器架構(gòu)幾種典型的基礎(chǔ)框架,你了解嗎?
NVIDIA 發(fā)布保障代理式 AI 應(yīng)用安全的 NIM 微服務(wù)
微服務(wù)容器化部署好處多嗎?
容器化能替代微服務(wù)嗎??jī)烧哂泻螀^(qū)別
寶藏級(jí)微服務(wù)架構(gòu)工具合集
NVIDIA NIM微服務(wù)登陸亞馬遜云科技
SSR與微服務(wù)架構(gòu)的結(jié)合應(yīng)用
微服務(wù)架構(gòu)與容器云的關(guān)系與區(qū)別
入門級(jí)攻略:如何容器化部署微服務(wù)?
Proxyless的多活流量和微服務(wù)治理

NVIDIA NIM微服務(wù)帶來(lái)巨大優(yōu)勢(shì)
采用OpenUSD和NVIDIA NIM微服務(wù)創(chuàng)建精準(zhǔn)品牌視覺
全新 NVIDIA NeMo Retriever微服務(wù)大幅提升LLM的準(zhǔn)確性和吞吐量

評(píng)論