什么是微服務(wù)膘茎?微服務(wù)的介紹

一、什么是微服務(wù)?

  微服務(wù)是一種面向服務(wù)的架構(gòu)(SOA)風(fēng)格(Java開(kāi)發(fā)人員最重要的技能之一)酷誓,其中披坏,應(yīng)用程序被構(gòu)建為多個(gè)不同的小型服務(wù)的集合而不是單個(gè)應(yīng)用程序。與單個(gè)程序不同的是盐数,微服務(wù)讓你可以同時(shí)運(yùn)行多個(gè)獨(dú)立的應(yīng)用程序棒拂,而這些獨(dú)立的應(yīng)用程序可以使用不同的編碼或編程語(yǔ)言來(lái)創(chuàng)建。龐大而又復(fù)雜的應(yīng)用程序可以由多個(gè)可自行執(zhí)行的簡(jiǎn)單而又獨(dú)立的程序所組成玫氢。這些較小的程序組合在一起帚屉,可以提供龐大的單程序所具備的所有功能。

   微服務(wù)是一種面向服務(wù)的架構(gòu)風(fēng)格,具有靈活性和低成本兩個(gè)特點(diǎn).
   靈活性:  由于這些較小的應(yīng)用程序無(wú)需使用相同的編程語(yǔ)言,因此,開(kāi)發(fā)人員可以使用他們最熟悉的語(yǔ)言,這是靈活性.
   低成本:  由于他們都用自己擅長(zhǎng)的語(yǔ)言去開(kāi)發(fā),所以效率會(huì)高,相應(yīng)的開(kāi)發(fā)成本會(huì)降低.

二漾峡、什么是分布式?

所謂分布式,無(wú)非就是將一個(gè)系統(tǒng)拆分成多個(gè)子系統(tǒng)并分布到多個(gè)服務(wù)器上.

簡(jiǎn)單的說(shuō)攻旦,是指將用戶界面、控制臺(tái)服務(wù)生逸、數(shù)據(jù)庫(kù)管理三個(gè)層次部署在不同的位置上牢屋。其中用戶界面是客戶端實(shí)現(xiàn)的功能,控制臺(tái)服務(wù)是一個(gè)專門的服務(wù)器槽袄,數(shù)據(jù)管理是在一個(gè)專門的數(shù)據(jù)庫(kù)服務(wù)器上實(shí)現(xiàn)的烙无。

分布式常用框架:Dubbo,MQ消息隊(duì)列,Zookeeper等.

關(guān)于分布式服務(wù)框架Dubbo

1.服務(wù)注冊(cè)中心,不再需要寫死服務(wù)提供方地址遍尺,注冊(cè)中心基于接口名查詢服務(wù)提供者的IP地址截酷,并且能夠平滑添加或刪除服務(wù)提供者。
2.透明化的遠(yuǎn)程方法調(diào)用乾戏,就像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法迂苛,只需簡(jiǎn)單配置,沒(méi)有任何API侵入鼓择。

3.軟負(fù)載均衡及容錯(cuò)機(jī)制灾部,可在內(nèi)網(wǎng)替代F5等硬件負(fù)載均衡器.

關(guān)于MQ消息隊(duì)列(RabbitMQ、ZeroMQ惯退、ActiveMQ等.)

  在高并發(fā)分布式環(huán)境下赌髓,由于來(lái)不及同步處理,請(qǐng)求往往發(fā)生堵塞,比如說(shuō)锁蠕,大量的insert夷野、update之類的請(qǐng)求同時(shí)到達(dá)數(shù)據(jù)庫(kù),直接導(dǎo)致無(wú)所的行鎖和表鎖荣倾,甚至最后請(qǐng)求會(huì)堆積過(guò)多悯搔,從而觸發(fā)too many connections錯(cuò)誤。通過(guò)使用消息隊(duì)列舌仍,我們可以異步處理請(qǐng)求妒貌,從而緩解系統(tǒng)的壓力。

ACK機(jī)制——當(dāng)消費(fèi)者拿到消息的瞬間,隊(duì)列中的消息立即刪除.同時(shí)刪除 前臺(tái)頁(yè)面,緩存庫(kù),數(shù)據(jù)庫(kù) .(ACK機(jī)制保證了性能的高效.)

以上铸豁,原文鏈接:https://blog.csdn.net/qq_41582642/article/details/81016500

以下灌曙, 是更詳細(xì)的解釋。

前言
到底什么是微服務(wù)节芥?為什么要用微服務(wù)在刺?微服務(wù)主要來(lái)做一些什么?微服務(wù)有哪些優(yōu)勢(shì)头镊?什么樣的服務(wù)屬于微服務(wù)蚣驼?本文所有資料來(lái)源網(wǎng)絡(luò),我只是整理一下相艇,總結(jié)一下颖杏。僅供參考。

一坛芽、微服務(wù)介紹

  1. 微服務(wù)由來(lái)
    微服務(wù)最早由Martin Fowler與James Lewis于2014年共同提出留储,微服務(wù)架構(gòu)風(fēng)格是一種使用一套小服務(wù)來(lái)開(kāi)發(fā)單個(gè)應(yīng)用的方式途徑,每個(gè)服務(wù)運(yùn)行在自己的進(jìn)程中靡馁,并使用輕量級(jí)機(jī)制通信欲鹏,通常是HTTP API机久,這些服務(wù)基于業(yè)務(wù)能力構(gòu)建臭墨,并能夠通過(guò)自動(dòng)化部署機(jī)制來(lái)獨(dú)立部署,這些服務(wù)使用不同的編程語(yǔ)言實(shí)現(xiàn)膘盖,以及不同數(shù)據(jù)存儲(chǔ)技術(shù)胧弛,并保持最低限度的集中式管理。

  2. 為什么需要微服務(wù)侠畔?
    在傳統(tǒng)的IT行業(yè)軟件大多都是各種獨(dú)立系統(tǒng)的堆砌结缚,這些系統(tǒng)的問(wèn)題總結(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)的問(wèn)題
單體架構(gòu)在規(guī)模比較小的情況下工作情況良好达布,但是隨著系統(tǒng)規(guī)模的擴(kuò)大,它暴露出來(lái)的問(wèn)題也越來(lái)越多斩熊,主要有以下幾點(diǎn):

1.復(fù)雜性逐漸變高

比如有的項(xiàng)目有幾十萬(wàn)行代碼往枣,各個(gè)模塊之間區(qū)別比較模糊,邏輯比較混亂粉渠,代碼越多復(fù)雜性越高分冈,越難解決遇到的問(wèn)題。

2.技術(shù)債務(wù)逐漸上升

公司的人員流動(dòng)是再正常不過(guò)的事情霸株,有的員工在離職之前雕沉,疏于代碼質(zhì)量的自我管束,導(dǎo)致留下來(lái)很多坑去件,由于單體項(xiàng)目代碼量龐大的驚人坡椒,留下的坑很難被發(fā)覺(jué),這就給新來(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í)間就過(guò)去了碘耳,留給開(kāi)發(fā)者開(kāi)發(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)目姚淆,代碼量明顯減少孕蝉,遇到問(wèn)題也相對(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)所有的模塊開(kāi)發(fā)所使用的技術(shù)一樣,微服務(wù)每個(gè)模塊都可以使用不同的開(kāi)發(fā)技術(shù)媒惕,開(kāi)發(fā)模式更靈活系吩。

3.3 微服務(wù)與SOA區(qū)別
微服務(wù),從本質(zhì)意義上看妒蔚,還是 SOA 架構(gòu)穿挨。但內(nèi)涵有所不同,微服務(wù)并不綁定某種特殊的技術(shù)面睛,在一個(gè)微服務(wù)的系統(tǒng)中絮蒿,可以有 Java 編寫的服務(wù)尊搬,也可以有 Python編寫的服務(wù)叁鉴,他們是靠Restful架構(gòu)風(fēng)格統(tǒng)一成一個(gè)系統(tǒng)的。所以微服務(wù)本身與具體技術(shù)實(shí)現(xiàn)無(wú)關(guān)佛寿,擴(kuò)展性強(qiáng)幌墓。

  1. 微服務(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)一的上線過(guò)程筷登,統(tǒng)一的日志和審計(jì)方法,統(tǒng)一的調(diào)度方式哩盲,統(tǒng)一的訪問(wèn)入口等等前方。
    微服務(wù)的目的是有效的拆分應(yīng)用,實(shí)現(xiàn)敏捷開(kāi)發(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)的溝通成本也就能降低旱物。
  2. 什么樣的項(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ù)之間是松耦合的不铆。

  1. 微服務(wù)折分與設(shè)計(jì)
    從單體式結(jié)構(gòu)轉(zhuǎn)向微服務(wù)架構(gòu)中會(huì)持續(xù)碰到服務(wù)邊界劃分的問(wèn)題:比如,我們有user 服務(wù)來(lái)提供用戶的基礎(chǔ)信息裹唆,那么用戶的頭像和圖片等是應(yīng)該單獨(dú)劃分為一個(gè)新的service更好還是應(yīng)該合并到user服務(wù)里呢狂男?如果服務(wù)的粒度劃分的過(guò)粗,那就回到了單體式的老路品腹;如果過(guò)細(xì)岖食,那服務(wù)間調(diào)用的開(kāi)銷就變得不可忽視了,管理難度也會(huì)指數(shù)級(jí)增加舞吭。目前為止還沒(méi)有一個(gè)可以稱之為服務(wù)邊界劃分的標(biāo)準(zhǔn)泡垃,只能根據(jù)不同的業(yè)務(wù)系統(tǒng)加以調(diào)節(jié)。

拆分的大原則是當(dāng)一塊業(yè)務(wù)不依賴或極少依賴其它服務(wù)羡鸥,有獨(dú)立的業(yè)務(wù)語(yǔ)義蔑穴,為超過(guò)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ù)從開(kāi)發(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)整雄家。

  1. 微服務(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ù)開(kāi)發(fā)趟济,一個(gè)微服務(wù)一般完成某個(gè)特定的功能乱投,比如:訂單管理,用戶管理等顷编;

微服務(wù)之間通過(guò)一些輕量級(jí)的通信機(jī)制進(jìn)行通信戚炫,例如通過(guò)REST API或者RPC的方式進(jìn)行調(diào)用。

7.2 特點(diǎn)
易于開(kāi)發(fā)和維護(hù)

由于微服務(wù)單個(gè)模塊就相當(dāng)于一個(gè)項(xiàng)目媳纬,開(kāi)發(fā)這個(gè)模塊我們就只需關(guān)心這個(gè)模塊的邏輯即可双肤,代碼量和邏輯復(fù)雜度都會(huì)降低,從而易于開(kāi)發(fā)和維護(hù)钮惠。

啟動(dòng)較快

這是相對(duì)單個(gè)微服務(wù)來(lái)講的茅糜,相比于啟動(dòng)單體架構(gòu)的整個(gè)項(xiàng)目,啟動(dòng)某個(gè)模塊的服務(wù)速度明顯是要快很多的素挽。

局部修改容易部署

在開(kāi)發(fā)中發(fā)現(xiàn)了一個(gè)問(wèn)題蔑赘,如果是單體架構(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)講,完全不是問(wèn)題较屿,電影模塊通過(guò)什么方式來(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)問(wèn)題都會(huì)造成整個(gè)項(xiàng)目運(yùn)行出現(xiàn)異常,想要知道是哪個(gè)模塊造成的問(wèn)題往往是不容易的,因?yàn)槲覀儫o(wú)法一步一步通過(guò)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ù)结啼。

  1. 微服務(wù)開(kāi)發(fā)框架
    目前微服務(wù)的開(kāi)發(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ù)的開(kāi)發(fā))

Consul、etcd&etc.(微服務(wù)的模塊)

  1. Sprint cloud 和 Sprint boot區(qū)別
    Spring Boot:

旨在簡(jiǎn)化創(chuàng)建產(chǎn)品級(jí)的Spring應(yīng)用和服務(wù)郊愧,簡(jiǎn)化了配置文件朴译,使用嵌入式web服務(wù)器,含有諸多開(kāi)箱即用微服務(wù)功能属铁,可以和spring cloud聯(lián)合部署眠寿。

Spring Cloud:

微服務(wù)工具包,為開(kāi)發(fā)者提供了在分布式系統(tǒng)的配置管理焦蘑、服務(wù)發(fā)現(xiàn)盯拱、斷路器、智能路由、微代理狡逢、控制總線等開(kāi)發(fā)工具包宁舰。

具體區(qū)別可以點(diǎn)擊:https://blog.csdn.net/Soinice/article/details/83793722

二、微服務(wù)實(shí)踐先知

1. 客戶端如何訪問(wèn)這些服務(wù)奢浑?(API Gateway)

傳統(tǒng)的開(kāi)發(fā)方式蛮艰,所有的服務(wù)都是本地的,UI可以直接調(diào)用殷费,現(xiàn)在按功能拆分成獨(dú)立的服務(wù)印荔,跑在獨(dú)立的一般都在獨(dú)立的虛擬機(jī)上的 Java進(jìn)程了低葫∠晗郏客戶端UI如何訪問(wèn)他的?后臺(tái)有N個(gè)服務(wù)嘿悬,前臺(tái)就需要記住管理N個(gè)服務(wù)实柠,一個(gè)服務(wù)下線/更新/升級(jí),前臺(tái)就要重新部署善涨,這明顯不符合我們拆分的理念窒盐,特別當(dāng)前臺(tái)是移動(dòng)應(yīng)用的時(shí)候,通常業(yè)務(wù)變化的節(jié)奏更快钢拧。另外蟹漓,N個(gè)小服務(wù)的調(diào)用也是一個(gè)不小的網(wǎng)絡(luò)開(kāi)銷。還有一般微服務(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é)省流量夫壁,提升性能

提供安全,過(guò)濾沃疮,流控等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ù)出口葱她,解除他們之間的耦合撩扒,不過(guò)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)在基本最通用的有兩種方式泉手。這幾種方式黔寇,展開(kāi)來(lái)講都可以寫本書(shū),而且大家一般都比較熟悉細(xì)節(jié)了斩萌, 就不展開(kāi)講了缝裤。

REST(JAX-RS,Spring Boot)

RPC(Thrift, Dubbo)

異步消息調(diào)用(Kafka, Notify)

一般同步調(diào)用比較簡(jiǎn)單颊郎,一致性強(qiáng)憋飞,但是容易出調(diào)用問(wèn)題,性能體驗(yàn)上也會(huì)差些姆吭,特別是調(diào)用層次多的時(shí)候榛做。RESTful和RPC的比較也是一個(gè)很有意思的話題。一般REST基于HTTP内狸,更容易實(shí)現(xiàn)检眯,更容易被接受,服務(wù)端實(shí)現(xiàn)技術(shù)也更靈活些昆淡,各個(gè)語(yǔ)言都能支持锰瘸,同時(shí)能跨客戶端,對(duì)客戶端沒(méi)有特殊的要求昂灵,只要封裝了HTTP的SDK就能調(diào)用避凝,所以相對(duì)使用的廣一些。RPC也有自己的優(yōu)點(diǎn)倔既,傳輸協(xié)議更高效恕曲,安全更可控,特別在一個(gè)公司內(nèi)部渤涌,如果有統(tǒng)一個(gè)的開(kāi)發(fā)規(guī)范和統(tǒng)一的服務(wù)框架時(shí)佩谣,他的開(kāi)發(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)性能拖慢。不過(guò)需要付出的代價(jià)是一致性的減弱,需要接受數(shù)據(jù)最終一致性虹脯;還有就是后臺(tái)服務(wù)一般要 實(shí)現(xiàn)冪等性驴娃,因?yàn)橄l(fā)送出于性能的考慮一般會(huì)有重復(fù)(保證消息的被收到且僅收到一次對(duì)性能是很大的考驗(yàn));最后就是必須引入一個(gè)獨(dú)立的broker循集,如果公司內(nèi)部沒(mé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èn)壓力增加新的服務(wù)節(jié)點(diǎn)。服務(wù)之間如何相互感知奸例?服務(wù)如何管理彬犯?這就是服務(wù)發(fā)現(xiàn)的問(wèn)題了向楼。一般有兩類做法查吊,也各有優(yōu)缺點(diǎn)『桑基本都是通過(guò)zookeeper等類似技術(shù)做服務(wù)注冊(cè)信息的分布式管理逻卖。當(dāng)服務(wù)上線時(shí),服務(wù)提供者將自己的服務(wù)信息注冊(cè)到ZK(或類似框架)昭抒,并通過(guò)心跳維持長(zhǎng)鏈接评也,實(shí)時(shí)更新鏈接信息。服務(wù)調(diào)用者通過(guò)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ò)是不可靠的硝岗。通過(guò)微服務(wù)拆分能降低這個(gè)風(fēng)險(xiǎn),不過(guò)如果沒(méi)有特別的保障袋毙,結(jié)局肯定是噩夢(mèng)型檀。我們剛遇到一個(gè)線上故障就是一個(gè)很不起眼的SQL計(jì)數(shù)功能,在訪問(wèn)量上升時(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é)出問(wèn)題都不至于影響整體鏈路。相應(yīng)的手段有很多:

重試機(jī)制

限流

熔斷機(jī)制

負(fù)載均衡

降級(jí)(本地緩存) 這些方法基本上都很明確通用腰吟,就不詳細(xì)說(shuō)明了无埃。比如Netflix的Hystrix:https://github.com/Netflix/Hystrix

5. 微服務(wù)需要考慮的問(wèn)題

這里有一個(gè)圖非常好的總結(jié)微服務(wù)架構(gòu)需要考慮的問(wèn)題,包括

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ù)通過(guò)使用POST請(qǐng)求注冊(cè)自己的IPAddress和Port润樱。每30秒發(fā)送一個(gè)PUT請(qǐng)求刷新注冊(cè)信息。通過(guò)DELETE請(qǐng)求注銷服務(wù)羡棵∫既簦客戶端通過(guò)GET請(qǐng)求獲取可用的服務(wù)實(shí)例信息。 Netflix的高可用(Netflix achieves high availability )是通過(guò)在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客戶端通過(guò)查詢 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)者通過(guò)服務(wù)注冊(cè)表獲取具體的服務(wù)訪問(wèn)地址(ip+端口)去訪問(wèn)具體的服務(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)期沒(méi)有響應(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)聽(tīng)相應(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ù)載均衡的常見(jiàn)策略
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然后重新開(kāi)始淮野。此種負(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ù)載過(guò)重。

3.1.4 IP Hash
這種方式通過(guò)生成請(qǐng)求源IP的哈希值慎式,并通過(guò)這個(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)生極大的不同级遭,并沒(méi)有達(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ò)的方式就是讓這種蟻穴不要變大等脂。那么我們常見(jiàn)的降級(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í)性較高的讀操作秃励。可以通過(guò)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ā)熔斷器打開(kāi)食呻,有程序自動(dòng)切斷當(dāng)前的RPC調(diào)用,來(lái)防止錯(cuò)誤進(jìn)一步擴(kuò)大流炕。實(shí)現(xiàn)一個(gè)熔斷器主要是考慮三種模式,關(guān)閉仅胞,打開(kāi)每辟,半開(kāi)。各個(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í)過(guò)高導(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)的額外開(kāi)銷婶熬。還要注意,熔斷器不能作為應(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)換到開(kāi)啟( Open )狀態(tài)。在開(kā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)換到半開(kāi)啟( Half-Open )狀態(tài)衣盾。

開(kāi)啟( Open ):在此狀態(tài)下,執(zhí)行對(duì)應(yīng)的操作將會(huì)立即失敗并且立即拋出異常爷抓。

半開(kāi)啟( 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)換到開(kāi)啟狀態(tài)并再次開(kāi)啟計(jì)時(shí)器(再給系統(tǒng)一些時(shí)間使其從失敗中恢復(fù))

6. 限流和降級(jí)

保證核心服務(wù)的穩(wěn)定性耘沼。為了保證核心服務(wù)的穩(wěn)定性极颓,隨著訪問(wèn)量的不斷增加,需要為系統(tǒng)能夠處理的服務(wù)數(shù)量設(shè)置一個(gè)極限閥值群嗤,超過(guò)這個(gè)閥值的請(qǐng)求則直接拒絕。同時(shí)兵琳,為了保證核心服務(wù)的可用狂秘,可以對(duì)否些非核心服務(wù)進(jìn)行降級(jí)骇径,通過(guò)限制服務(wù)的最大訪問(wèn)量進(jìn)行限流,通過(guò)管理控制臺(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ò)變化之前的通知安排拥刻;

撥入訪問(wèn)可用性怜瞒;

運(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)更專注于安全、流量宦棺、路由等問(wèn)題瓣距。

9. 多級(jí)緩存

最簡(jiǎn)單的緩存就是查一次數(shù)據(jù)庫(kù)然后將數(shù)據(jù)寫入緩存比如redis中并設(shè)置過(guò)期時(shí)間。因?yàn)橛羞^(guò)期失效因此我們要關(guān)注下緩存的穿透率代咸,這個(gè)穿透率的計(jì)算公式蹈丸,比如查詢方法queryOrder(調(diào)用次數(shù)1000/1s)里面嵌套查詢DB方法queryProductFromDb(調(diào)用次數(shù)300/s),那么redis的穿透率就是300/1000,在這種使用緩存的方式下,是要重視穿透率的逻杖,穿透率大了說(shuō)明緩存的效果不好奋岁。還有一種使用緩存的方式就是將緩存持久化,也就是不設(shè)置過(guò)期時(shí)間荸百,這個(gè)就會(huì)面臨一個(gè)數(shù)據(jù)更新的問(wèn)題闻伶。一般有兩種辦法,一個(gè)是利用時(shí)間戳够话,查詢默認(rèn)以redis為主蓝翰,每次設(shè)置數(shù)據(jù)的時(shí)候放入一個(gè)時(shí)間戳,每次讀取數(shù)據(jù)的時(shí)候用系統(tǒng)當(dāng)前時(shí)間和上次設(shè)置的這個(gè)時(shí)間戳做對(duì)比女嘲,比如超過(guò)5分鐘畜份,那么就再查一次數(shù)據(jù)庫(kù)。這樣可以保證redis里面永遠(yuǎn)有數(shù)據(jù)澡为,一般是對(duì)DB的一種容錯(cuò)方法漂坏。還有一個(gè)就是真正的讓redis做為DB使用。就是圖里面畫的通過(guò)訂閱數(shù)據(jù)庫(kù)的binlog通過(guò)數(shù)據(jù)異構(gòu)系統(tǒng)將數(shù)據(jù)推送給緩存媒至,同時(shí)將將緩存設(shè)置為多級(jí)顶别。可以通過(guò)使用jvmcache作為應(yīng)用內(nèi)的一級(jí)緩存拒啰,一般是體積小驯绎,訪問(wèn)頻率大的更適合這種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ò)沒(méi)有問(wèn)題。那么時(shí)間都花在什么地方了呢泞坦,兩種原因窖贤,客戶端調(diào)用方,還有一個(gè)原因是網(wǎng)絡(luò)發(fā)生TCP重傳贰锁。所以要注意這兩點(diǎn)赃梧。

11. 線程池隔離

  在抗量這個(gè)環(huán)節(jié),Servlet3異步的時(shí)候豌熄,有提到過(guò)線程隔離授嘀。線程隔離的之間優(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èn)訂單服務(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)能保證局部問(wèn)題不會(huì)影響全局芯丧。

12. 降級(jí)和限流

 關(guān)于降級(jí)限流的方法業(yè)界都已經(jīng)有很成熟的方法了,比如FAILBACK機(jī)制世曾,限流的方法令牌桶缨恒,漏桶谴咸,信號(hào)量等。這里談一下我們的一些經(jīng)驗(yàn)骗露,降級(jí)一般都是由統(tǒng)一配置中心的降級(jí)開(kāi)關(guān)來(lái)實(shí)現(xiàn)的岭佳,那么當(dāng)有很多個(gè)接口來(lái)自同一個(gè)提供方,這個(gè)提供方的系統(tǒng)或這機(jī)器所在機(jī)房網(wǎng)絡(luò)出現(xiàn)了問(wèn)題萧锉,我們就要有一個(gè)統(tǒng)一的降級(jí)開(kāi)關(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ī)限流封寞,并沒(méi)有實(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中还蹲,通過(guò)web查詢。現(xiàn)在做的追蹤功能還比較簡(jiǎn)單耙考,這塊還需要繼續(xù)豐富谜喊。

建議先了解分布式理論,再看微服務(wù)倦始。

作者:Soinice
來(lái)源:CSDN
原文:https://blog.csdn.net/Soinice/article/details/83989225
版權(quán)聲明:本文為博主原創(chuàng)文章斗遏,轉(zhuǎn)載請(qǐng)附上博文鏈接!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鞋邑,一起剝皮案震驚了整個(gè)濱河市诵次,隨后出現(xiàn)的幾起案子账蓉,更是在濱河造成了極大的恐慌,老刑警劉巖逾一,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铸本,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遵堵,警方通過(guò)查閱死者的電腦和手機(jī)箱玷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鄙早,“玉大人汪茧,你說(shuō)我怎么就攤上這事∠薹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵呀舔,是天一觀的道長(zhǎng)弥虐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)媚赖,這世上最難降的妖魔是什么霜瘪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮惧磺,結(jié)果婚禮上颖对,老公的妹妹穿的比我還像新娘。我一直安慰自己磨隘,他們只是感情好缤底,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著番捂,像睡著了一般个唧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上设预,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天徙歼,我揣著相機(jī)與錄音,去河邊找鬼鳖枕。 笑死魄梯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宾符。 我是一名探鬼主播酿秸,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吸奴!你這毒婦竟也來(lái)了允扇?” 一聲冷哼從身側(cè)響起缠局,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎考润,沒(méi)想到半個(gè)月后狭园,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡糊治,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年唱矛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片井辜。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绎谦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粥脚,到底是詐尸還是另有隱情窃肠,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布刷允,位于F島的核電站冤留,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏树灶。R本人自食惡果不足惜纤怒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望天通。 院中可真熱鬧泊窘,春花似錦、人聲如沸像寒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)树碱。三九已至,卻和暖如春竿秆,著一層夾襖步出監(jiān)牢的瞬間序臂,已是汗流浹背蚌卤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奥秆,地道東北人逊彭。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像构订,于是被迫代替她去往敵國(guó)和親侮叮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355