<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          肝了兩萬(wàn)字的springcloud,錯(cuò)過(guò)了血虧!

          共 11024字,需瀏覽 23分鐘

           ·

          2021-09-26 13:44



          前言

          我們會(huì)首先介紹一下網(wǎng)絡(luò)中的名詞,讓大家更好的更熟悉的去理解復(fù)雜業(yè)務(wù)系統(tǒng)之間的交互,如果你是一個(gè)小萌新,千萬(wàn)不要被網(wǎng)絡(luò)中的各種名詞唬住,你只需要記住,萬(wàn)變不離其宗,這些只是五花八門(mén)的名詞而已,原理大概率也就那么回事~

          熟悉我的小伙伴都知道我不是計(jì)算機(jī)軟件專業(yè)的,是一個(gè)完完全全的自學(xué)黨,就像我剛剛大三的時(shí)候,開(kāi)始自學(xué)Java,因?yàn)槲覍I(yè)不學(xué),所以只能自學(xué)咯,至于具體的原由,大家移步到我的個(gè)人生活篇,來(lái)走進(jìn)我的內(nèi)心~

          當(dāng)時(shí)的我,也算是Java界的小萌新,學(xué)習(xí)spring的過(guò)程中聽(tīng)到IOCAOP這種名詞,當(dāng)時(shí)的感覺(jué)只能說(shuō)是牛逼,感覺(jué)瞬間檔次就上來(lái)了,然后自己的懵逼感也是成倍的增加,當(dāng)時(shí)大概的感覺(jué)就是完全被這些個(gè)花花名詞給唬住了

          再說(shuō)一些小插曲

          在學(xué)習(xí)Java的過(guò)程中就接觸到了當(dāng)時(shí)感覺(jué)超級(jí)牛X的SSM,我竟一度認(rèn)為只要我學(xué)會(huì)SSM,就可以很厲害

          你能不能想象當(dāng)時(shí)我自己按照視頻教程搭建了一套SSM,然后畫(huà)了一個(gè)巨抽象的頁(yè)面和寫(xiě)了幾個(gè)巨簡(jiǎn)單的數(shù)據(jù)庫(kù)查詢接口,JDBC,大家都懂得,直接一套連接,增刪改查,哎喲喂,當(dāng)時(shí)的那個(gè)心情啊,簡(jiǎn)直就是叫花子哼著太平調(diào)-窮開(kāi)心

          現(xiàn)在想起來(lái)真是不知天高地厚

          這一篇沒(méi)有什么源碼的講解,基本都是通過(guò)聊天的方式來(lái)讓大家在潛移默化中熟悉網(wǎng)絡(luò)中的一些基礎(chǔ)概念和了解springcloud中的部分常用組件的功能

          先來(lái)個(gè)簡(jiǎn)介

          先給大家看一張圖,如果你完全明白整個(gè)架構(gòu)圖,恭喜你,太棒了,如果你能夠自己畫(huà)出來(lái)整個(gè)結(jié)構(gòu)圖,能夠深刻的理解每個(gè)組件的真正作用,該組件在此系統(tǒng)中的存在的意義,那恭喜你,下次面試直接架構(gòu)師起步

          哈哈,開(kāi)個(gè)玩笑,簡(jiǎn)單給大家說(shuō)一遍先,大家先嘗試著理解一遍

          客戶端請(qǐng)求進(jìn)來(lái)之后,首先是Nginx負(fù)載均衡,這個(gè)大家應(yīng)該都聽(tīng)過(guò)吧,屬于一個(gè)高性能的HTTP和反向代理的服務(wù)器,反向代理是對(duì)客戶端無(wú)感知的,這個(gè)東西的作用就是讓非常多的客戶請(qǐng)求均勻的分配到相應(yīng)的服務(wù)器

          接下來(lái)就是服務(wù)網(wǎng)關(guān),這個(gè)東西還是很重要的,很多公司也都會(huì)用,屬于跨服務(wù)的代理,可以進(jìn)行路由轉(zhuǎn)發(fā),鑒權(quán)等,保護(hù)系統(tǒng)很有用

          然后我們內(nèi)部看到很多的業(yè)務(wù)服務(wù)群service,這些當(dāng)然就是我們平時(shí)接觸最多的服務(wù)咯,你每天寫(xiě)的接口就是屬于這一層的,我們可以看到在服務(wù)的左右側(cè)都有很多東西,這些小組件各個(gè)都是小能手,各有各的能耐

          屬于天生我材必有用的那種

          Eureka和Consul都是屬于服務(wù)治理組件,寫(xiě)的業(yè)務(wù)service就是注冊(cè)到這里,然后可以被其它的服務(wù)發(fā)現(xiàn)并且調(diào)用

          Config這個(gè)屬于一個(gè)配置中心,每個(gè)服務(wù)都會(huì)有很多配置文件,這些可能會(huì)有很多公共的地方,而且也比較難于管理,甚至你改一個(gè)配置文件都需要重新部署這個(gè)項(xiàng)目,用了這個(gè)我們就不用每次都重啟服務(wù)啦,可以實(shí)現(xiàn)"熱部署"了

          Hystrix容錯(cuò)保護(hù)+Turbine集群監(jiān)控+Sleuth鏈路跟蹤,這一套下來(lái),保護(hù)系統(tǒng)不會(huì)掛掉,可以進(jìn)行服務(wù)降級(jí),出現(xiàn)問(wèn)題有跡可循

          springcloud bus消息總線,config可以解決不重啟情況下更新配置,但是我們需要一個(gè)服務(wù)一個(gè)服務(wù)的發(fā)送post請(qǐng)求,也是稍微有點(diǎn)麻煩的,這種情況下大家應(yīng)該想到了消息隊(duì)列的發(fā)布訂閱模型了吧,我們通過(guò)bus就可以實(shí)現(xiàn),只需要在config server端發(fā)起refresh,就可以觸發(fā)所有微服務(wù)的更新了

          springcloud task任務(wù)調(diào)度,定時(shí)任務(wù),比如每天凌晨一點(diǎn)清空昨天的無(wú)用數(shù)據(jù)

          springcloud data flow數(shù)據(jù)流操作,用于處理數(shù)據(jù)量較大的處理,批量運(yùn)算和持續(xù)運(yùn)算這種

          和springcloud stream流操作,解決系統(tǒng)中不同中間件的適配問(wèn)題,自動(dòng)適配,給不同的MQ之間進(jìn)行切換

          什么是spring cloud

          springcloud屬于一個(gè)系列框架的有序集合,就是一個(gè)全家桶系列。不知道大家知道Spring boot嗎,cloud就是基于boot,boot更像是一個(gè)便捷的單點(diǎn)開(kāi)發(fā)框架,幫助大家解決各種配置文件的煩惱

          而cloud呢,是一個(gè)大集合,基于springboot的,為了微服務(wù)體系開(kāi)發(fā)中的架構(gòu)問(wèn)題,屬于一套組件,提供了一整套的解決方案

          它利用spring boot的開(kāi)發(fā)便利性巧妙的簡(jiǎn)化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開(kāi)發(fā),比如服務(wù)發(fā)現(xiàn)注冊(cè)、消息總線、配置中心、負(fù)載均衡、熔斷器這些,都可以用springboot的開(kāi)發(fā)風(fēng)格來(lái)做到一鍵啟動(dòng)和部署,更為便捷

          springcloud中的微服務(wù)是可以獨(dú)立部署、水平擴(kuò)展,以及獨(dú)立訪問(wèn),springcloud屬于這些組件的大管家,在這一點(diǎn)類(lèi)似于我們說(shuō)的Hadoop全家桶吧,包含很多相應(yīng)的處理框架,當(dāng)然Hadoop本身也是一個(gè)大數(shù)據(jù)處理框架

          集群

          先來(lái)看下百度百科對(duì)于集群技術(shù)的講解,兩個(gè)關(guān)鍵詞,相互獨(dú)立和組,特點(diǎn):

          1、高可用性,獨(dú)立性,A掛了并不會(huì)對(duì)系統(tǒng)造成太大影響,B還可以繼續(xù)工作

          2、提高效率,集群可以提高系統(tǒng)的工作效率

          我們一起來(lái)看例子:你厭倦了上班的生活,決定換一種活法,于是決定,辭職創(chuàng)業(yè)!

          你有了一個(gè)好點(diǎn)子,開(kāi)發(fā)了一個(gè)打車(chē)小程序滴滴打打,剛開(kāi)始寫(xiě)好了直接發(fā)布,四面八方的用戶來(lái)注冊(cè)了,前期沒(méi)問(wèn)題,服務(wù)器頂?shù)米。请S著用戶量越來(lái)越大,你部署的一臺(tái)服務(wù)器頂不住了,怎么辦呢,加內(nèi)存,加CPU,但是這些還是不夠用的

          于是有了一個(gè)簡(jiǎn)單暴力的法子,加機(jī)器!只有花錢(qián)才能變強(qiáng),沒(méi)錯(cuò),原先是只有一臺(tái)服務(wù)器A來(lái)提供服務(wù),現(xiàn)在加了個(gè)服務(wù)器BAB可以提供同樣的服務(wù),A掛了B可以頂上,AB同心協(xié)力,AB就組成了一個(gè)小集群!

          集群,用于給各個(gè)服務(wù)器間分擔(dān)壓力!

          分布式和微服務(wù),傻傻分不清楚

          從概念理解,分布式服務(wù)架構(gòu)強(qiáng)調(diào)的是服務(wù)化以及服務(wù)的分散化,微服務(wù)則更強(qiáng)調(diào)服務(wù)的專業(yè)化和精細(xì)分工

          從實(shí)踐的角度來(lái)看,微服務(wù)架構(gòu)通常是分布式服務(wù)架構(gòu),反之則未必成立。所以,選擇微服務(wù)通常意味著需要解決分布式架構(gòu)的各種難題。

          這樣來(lái)看可能比較晦澀難懂,我們繼續(xù)來(lái)看例子:

          隨著我們的滴滴打打系統(tǒng)發(fā)展越來(lái)越龐大,作為一個(gè)后端工程師,首先要考慮的當(dāng)然是后端了,你想啊,后端代碼越來(lái)越多,越來(lái)越臃腫,于是,微服務(wù)就上場(chǎng)了

          我們可以把這一個(gè)系統(tǒng)按照業(yè)務(wù)劃分為用戶模塊、支付模塊、訂單模塊等等,每個(gè)服務(wù)內(nèi)部是獨(dú)立的,對(duì)外開(kāi)放接口,供外部調(diào)用

          這樣后端開(kāi)發(fā)起來(lái)也是很方便的,對(duì)于系統(tǒng)的架構(gòu)也都是獨(dú)立的,怎么說(shuō)呢,就是比如你這次需求的改動(dòng)只是針對(duì)于用戶模塊這一個(gè)服務(wù),你就只需要重啟用戶模塊即可了,別的服務(wù)不需要重啟,至于別的服務(wù)調(diào)用用戶模塊服務(wù)也會(huì)進(jìn)行熱切換(只有當(dāng)新的服務(wù)部署成功了,運(yùn)行穩(wěn)定了,才會(huì)下掉老服務(wù)

          微服務(wù)的設(shè)計(jì)是為了不因?yàn)槟硞€(gè)模塊的升級(jí)和BUG影響現(xiàn)有的系統(tǒng)業(yè)務(wù)。微服務(wù)與分布式的細(xì)微差別是,微服務(wù)的應(yīng)用不一定是分散在多個(gè)服務(wù)器上,他也可以是同一個(gè)服務(wù)器。

          至于分布式呢,你想啊,如果用戶模塊這個(gè)服務(wù)只有一個(gè),只部署在一個(gè)機(jī)器上,那這就是個(gè)大漏洞,是個(gè)很糟糕的設(shè)計(jì),如果這個(gè)機(jī)器掛掉了,那這個(gè)用戶模塊就GG了,整個(gè)系統(tǒng)應(yīng)該也就完蛋了,因?yàn)橛脩裟K屬于很核心的,各個(gè)服務(wù)都和它息息相關(guān)

          于是就有了分布式,我們把這個(gè)用戶模塊服務(wù),部署在多臺(tái)機(jī)器上,當(dāng)然不一定是所有機(jī)器都部署這個(gè)服務(wù),夠用就好,剩下的內(nèi)存空間留給別的服務(wù)咯,你這一個(gè)機(jī)器基本不可能只部署這一個(gè)服務(wù)的,這樣太浪費(fèi)機(jī)器了,直白點(diǎn)就是,太浪費(fèi)錢(qián)了!

          看上面的圖,大概就這意思,這個(gè)系統(tǒng)有ABC三個(gè)機(jī)器,沒(méi)了哪個(gè)機(jī)器,這個(gè)系統(tǒng)都暫時(shí)可以使用,當(dāng)然承受壓力的能力會(huì)小一些,這個(gè)時(shí)候運(yùn)維工程師就出動(dòng)了,需要檢查這個(gè)機(jī)器到底是怎么了,來(lái)盡快的恢復(fù)該機(jī)器的運(yùn)轉(zhuǎn),加入這個(gè)分布式

          總結(jié)一下:微服務(wù):分散能力。分布式:分散部署。

          CAP理論

          CAP理論這個(gè)大家應(yīng)該聽(tīng)的耳朵都出繭子了吧,不知道大家有沒(méi)有真正的理解

          Anyway,看完這篇文章之后,你就肯定懂了

          先看下CAP分別代表什么

          一致性(Consistency):所有節(jié)點(diǎn)訪問(wèn)同一份最新的數(shù)據(jù)副本

          可用性(Availability):每次請(qǐng)求都能獲取到非錯(cuò)的響應(yīng),但是不保證獲取的數(shù)據(jù)為最新數(shù)據(jù)

          分區(qū)容錯(cuò)性(Partition tolerance):分布式系統(tǒng)在遇到任何網(wǎng)絡(luò)分區(qū)故障的時(shí)候,仍然能夠?qū)ν馓峁M足一致性和可用性的服務(wù),除非整個(gè)網(wǎng)絡(luò)環(huán)境都發(fā)生了故障

          簡(jiǎn)單看下每個(gè)代表的含義:

          一致性,這里的一致性指的是強(qiáng)一致性,即每個(gè)節(jié)點(diǎn)的數(shù)據(jù)都是最新的版本,其實(shí)一致性級(jí)別還有弱一致性和最終一致性這種

          • 弱一致性:弱一致性是相對(duì)于強(qiáng)一致性而言,它不保證總能得到最新的值;

          • 最終一致性(eventual consistency):放寬對(duì)時(shí)間的要求,在被調(diào)完成操作響應(yīng)后的某個(gè)時(shí)間點(diǎn),被調(diào)多個(gè)節(jié)點(diǎn)的數(shù)據(jù)最終達(dá)成一致

          在寫(xiě)操作完成后開(kāi)始的任何讀操作都必須返回該值,或者后續(xù)寫(xiě)操作的結(jié)果,也就是說(shuō),在一致性系統(tǒng)中,一旦客戶端將值寫(xiě)入任何一臺(tái)服務(wù)器并獲得響應(yīng),那么之后client從其他任何服務(wù)器讀取的都是剛寫(xiě)入的數(shù)據(jù)

          可用性:系統(tǒng)中非故障節(jié)點(diǎn)收到的每個(gè)請(qǐng)求都必須有響應(yīng),在可用系統(tǒng)中,如果我們的客戶端向服務(wù)器發(fā)送請(qǐng)求,并且服務(wù)器未崩潰,則服務(wù)器必須最終響應(yīng)客戶端,不允許服務(wù)器忽略客戶的請(qǐng)求

          分區(qū)容錯(cuò)性:允許網(wǎng)絡(luò)丟失從一個(gè)節(jié)點(diǎn)發(fā)送到另一個(gè)節(jié)點(diǎn)的任意多條消息,即不同步

          CAP三者不能同時(shí)滿足

          這一點(diǎn)大家應(yīng)該也聽(tīng)過(guò)了,但是為什么呢,可能有很多人就不曉得了,我們來(lái)用反證法證明一下

          假設(shè)都滿足,首先滿足分區(qū)容錯(cuò)性,那就意味著節(jié)點(diǎn)A和節(jié)點(diǎn)B的數(shù)據(jù)會(huì)存在一些偏差,如果滿足可用性,則證明有用戶發(fā)來(lái)請(qǐng)求,則必須響應(yīng),也就意味著響應(yīng)給客戶端的請(qǐng)求會(huì)存在一些數(shù)據(jù)偏差,因?yàn)椴煌恼?qǐng)求可能打到不同的節(jié)點(diǎn)

          此時(shí)就不滿足數(shù)據(jù)一致性了,三者是矛盾的,不能同時(shí)成立

          注冊(cè)中心

          隨著系統(tǒng)的架構(gòu)越來(lái)越復(fù)雜,將業(yè)務(wù)切分成多個(gè)獨(dú)立的服務(wù),來(lái)降低系統(tǒng)的耦合性,而每個(gè)服務(wù)又要部署在多個(gè)機(jī)器上,來(lái)保證系統(tǒng)的穩(wěn)定性

          林子大了,自然是什么鳥(niǎo)都有,于是管理這些服務(wù)的組件自然就誕生了,系統(tǒng)中包含用戶中心、注冊(cè)中心、支付中心、訂單中心這些,用戶中心可能部署到多個(gè)服務(wù)器上,這也就意味著多個(gè)IP和端口號(hào),那難道在每個(gè)調(diào)用用戶中心服務(wù)的地方都去把這些IP和端口號(hào)都寫(xiě)死在調(diào)用的地方嗎

          這樣肯定是不合適的,而且如果后續(xù)有大流量進(jìn)來(lái),決定臨時(shí)加機(jī)器,還要來(lái)修改代碼,肯定是不人性化的,不符合我們的解耦合原則

          對(duì)于我這種北漂族來(lái)說(shuō)有一個(gè)形象的例子給到大家,租房子,你首先想到的是找房東還是中介呢,我反正想到的是中介。房東就是服務(wù)提供者Provider,我就是服務(wù)消費(fèi)者Consumer,但是呢,我沒(méi)法找到相應(yīng)的房東,因?yàn)榉繓|太多了,我也不知道該怎么找

          如果單靠房東和類(lèi)似我這種租客來(lái)交互是很麻煩的,效率也是很低的,于是就出現(xiàn)了中介這個(gè)行業(yè),中介這個(gè)行業(yè)進(jìn)行信息的匯總和派遣,利用信息差來(lái)賺錢(qián)


          房東想租房子了,把信息注冊(cè)到中介,我想租房子了,也聯(lián)系中介,中介便可以為我找到合適的房源

          再看Eureka

          在眾多的微服務(wù)中,管理起來(lái)也是一件麻煩事,于是乎就有了Eureka注冊(cè)中心這個(gè)家伙。Eureka就和上面的中介一樣,去匯總服務(wù)提供者和消費(fèi)者的信息,做一個(gè)第三者


          服務(wù)的提供者:服務(wù)的注冊(cè),服務(wù)的同步,服務(wù)的續(xù)約

          服務(wù)的注冊(cè):啟動(dòng)的時(shí)候會(huì)通過(guò)發(fā)送REST請(qǐng)求的方式將自己注冊(cè)到Eureka Server上,同時(shí)帶上了自身服務(wù)的一些元數(shù)據(jù)信息

          服務(wù)的同步:在實(shí)際的生成環(huán)境中,注冊(cè)中心往往是集群部署的,這個(gè)時(shí)候就會(huì)涉及到服務(wù)的同步,同步的前提條件就是:注冊(cè)中心首先要相互注冊(cè),這樣當(dāng)一個(gè)服務(wù)提供者發(fā)起請(qǐng)求到注冊(cè)中心進(jìn)行注冊(cè),它會(huì)將該請(qǐng)求轉(zhuǎn)發(fā)給集群相連的其他注冊(cè)中心,實(shí)現(xiàn)了注冊(cè)中之間的服務(wù)同步。

          服務(wù)的續(xù)約:完成注冊(cè)之后,注冊(cè)中心就通過(guò)心跳機(jī)制檢查各個(gè)服務(wù)是否還存活著,如果超過(guò)了配置參數(shù)定義的是就會(huì)將服務(wù)移除注冊(cè)中心。

          服務(wù)的消費(fèi)者:獲取服務(wù)、服務(wù)調(diào)用、服務(wù)下線

          獲取服務(wù):消費(fèi)者服務(wù)進(jìn)行消費(fèi)的的時(shí)候會(huì)發(fā)起一個(gè)REST請(qǐng)求到注冊(cè)中心獲取注冊(cè)到注冊(cè)中心的服務(wù)列表,這個(gè)服務(wù)列表按照上面配置會(huì)30s中更新一次。

          服務(wù)調(diào)用:消費(fèi)者在獲取服務(wù)清單后,通過(guò)服務(wù)名獲取服務(wù)的實(shí)例名,和該實(shí)例的元數(shù)據(jù)(ip + 端口等),Eureka底層會(huì)通過(guò)Ribbon默認(rèn)采用訊輪的方式進(jìn)行調(diào)用從而實(shí)現(xiàn)了客戶端的負(fù)載均衡。

          服務(wù)下線:我們服務(wù)重啟或者關(guān)閉服務(wù)的時(shí)候,要主動(dòng)告訴注冊(cè)中心。當(dāng)服務(wù)正常關(guān)機(jī)的時(shí)候回發(fā)起一個(gè)REST請(qǐng)求到注冊(cè)中心。注冊(cè)中心收到請(qǐng)求之后就會(huì)把服務(wù)從注冊(cè)列表中剔除。

          注冊(cè)中心:實(shí)效剔除、自我保護(hù)

          實(shí)效剔除:上面講了服務(wù)的下線是服務(wù)正常關(guān)閉。當(dāng)服務(wù)非正常關(guān)閉(內(nèi)存溢出,網(wǎng)絡(luò)故障等)服務(wù)不能正常工作,而注冊(cè)中心沒(méi)有收到服務(wù)下線的請(qǐng)求,這個(gè)時(shí)候該腫么辦呢?注冊(cè)中心會(huì)定時(shí)沒(méi)每隔一段時(shí)間(默認(rèn)是60s)將服務(wù)列表超時(shí)的服務(wù)(90s)沒(méi)有續(xù)約的服務(wù)剔除出去。

          自我保護(hù):之前我們知道服務(wù)注冊(cè)到注冊(cè)中心之后會(huì)維持一個(gè)心跳機(jī)制,當(dāng)然心跳也會(huì)有失敗的時(shí)候,這個(gè)時(shí)候注冊(cè)中心,會(huì)統(tǒng)計(jì)失敗比例在15分鐘之后低于百分之85的,會(huì)將當(dāng)前服務(wù)保護(hù)起來(lái),當(dāng)這些服務(wù)不會(huì)過(guò)期。在保護(hù)的這個(gè)階段消費(fèi)者很可能調(diào)用了不存在的服務(wù),所以消費(fèi)者一般都會(huì)有容錯(cuò)機(jī)制,請(qǐng)求重試,斷路器等當(dāng)然這個(gè)自我保護(hù)可以通過(guò)以下配置進(jìn)行自行配置。

          負(fù)載均衡

          來(lái)想個(gè)場(chǎng)景,用戶服務(wù)A部署在1、23三臺(tái)節(jié)點(diǎn)上,并且我們通過(guò)上述注冊(cè)中心可以拿到這三臺(tái)節(jié)點(diǎn)的IP和port,但是問(wèn)題也隨而來(lái)了,調(diào)用哪一臺(tái)呢

          小孩子才做選擇,我全都要??!

          在調(diào)用用戶服務(wù)A的時(shí)候,會(huì)將請(qǐng)求打到相應(yīng)的節(jié)點(diǎn)上,但是在選擇節(jié)點(diǎn)上也是一個(gè)大問(wèn)題,在一些小系統(tǒng)的時(shí)候這些其實(shí)倒還好一些,只要服務(wù)器頂?shù)米?,即使全打到同一個(gè)節(jié)點(diǎn)上,也能頂?shù)米?/span>

          但是當(dāng)系統(tǒng)擴(kuò)大到一定規(guī)模的時(shí)候,如果請(qǐng)求我們沒(méi)法合理的控制去向,則會(huì)變成災(zāi)難,你想啊,本來(lái)20臺(tái)機(jī)子上都部署了用戶服務(wù),結(jié)果呢,請(qǐng)求全都打到其中一個(gè)機(jī)器上了,那不GG,老板這下該罵娘了,花了西瓜的錢(qián),結(jié)果只用了個(gè)西瓜皮,別的全打水漂了

          問(wèn)題我們說(shuō)清楚了,于是負(fù)載均衡閃亮登場(chǎng)了

          大家在此之前可能聽(tīng)過(guò)負(fù)載均衡這一概念,負(fù)載均衡又可以分為兩種,客戶端負(fù)載均衡和服務(wù)端負(fù)載均衡

          客戶端負(fù)載均衡,服務(wù)清單保存在客戶端,客戶端進(jìn)行負(fù)載均衡算法,在請(qǐng)求發(fā)出之前已經(jīng)確定了這個(gè)請(qǐng)求的去向,springcloud下的ribbon就是屬于客戶端負(fù)載均衡

          服務(wù)端負(fù)載均衡,服務(wù)清單保存在服務(wù)端,對(duì)于客戶端是無(wú)感知的,對(duì)外開(kāi)放一個(gè)域名,所有客戶端都往這上面打請(qǐng)求。最熟悉的就是Nginx了,這個(gè)用的很多

          再提一嘴,我們也可以根據(jù)節(jié)點(diǎn)的性能去控制請(qǐng)求的數(shù)量,比如某個(gè)機(jī)器就是牛x,我們可以通過(guò)調(diào)節(jié)算法,讓請(qǐng)求更青睞于這個(gè)節(jié)點(diǎn)

          再看Ribbon

          Ribbon的核心在RestTemplate,RestTemplateSpring提供的一個(gè)訪問(wèn)Http服務(wù)的客戶端類(lèi)

          怎么說(shuō)呢?就是微服務(wù)之間的調(diào)用是使用的RestTemplate。比如這個(gè)時(shí)候我們 消費(fèi)者B 需要調(diào)用 提供者A 所提供的服務(wù)我們就需要這么寫(xiě)。如我下面的偽代碼

          @Autowiredprivate RestTemplate restTemplate;// 這里是提供者A的ip地址,但是如果使用了 Eureka 那么就應(yīng)該是提供者A的名稱private static final String SERVICE_PROVIDER_A = "http://localhost:8081";
          @PostMapping("/dayu")public boolean dayu(@RequestBody Request request) { String url = SERVICE_PROVIDER_A + "/service1"; return restTemplate.postForObject(url, request, Boolean.class);}

          負(fù)載均衡,不管Nginx還是Ribbon都需要其算法的支持,Nginx使用的是輪詢和加權(quán)輪詢算法。而在Ribbon中有更多的負(fù)載均衡調(diào)度算法,其默認(rèn)是使用的RoundRobinRule輪詢策略。

          RoundRobinRule:輪詢策略。Ribbon默認(rèn)采用的策略。若經(jīng)過(guò)一輪輪詢沒(méi)有找到可用的provider,其最多輪詢 10 輪。若最終還沒(méi)有找到,則返回 null

          RandomRule: 隨機(jī)策略,從所有可用的 provider 中隨機(jī)選擇一個(gè)。

          RetryRule: 重試策略。先按照 RoundRobinRule 策略獲取 provider,若獲取失敗,則在指定的時(shí)限內(nèi)重試。默認(rèn)的時(shí)限為 500 毫秒。

          算法還有很多,這里就不一一列舉了,我們也是可以根據(jù)自己實(shí)際的需求自定義負(fù)載均衡策略的。

          實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單:繼承AbstractLoadBalancerRule類(lèi),重寫(xiě)public Server choose(ILoadBalancer lb, Object key)即可。

          Feign和OpenFeign

          有了 Eureka,RestTemplate,Ribbon我們就可以進(jìn)行服務(wù)間的調(diào)用了,但是使用RestTemplate還是不方便,我們每次調(diào)用的時(shí)候都要通過(guò)RestTemplateAPI來(lái)進(jìn)行服務(wù)的調(diào)用,感覺(jué)用起來(lái)總是不如意,沒(méi)有那種直接調(diào)用方法的便捷

          不知道大家有沒(méi)有使用過(guò)Dubbo,Dubbo就是可以直接使用的,比較方便,直接使用@Reference注解即可

          @ReferenceCustomerService customerService;
          Private void test(){ customerService.login(username , password);}

          Feign就是在內(nèi)部集成,屬于Spring Cloud組件中的一個(gè)輕量級(jí)RESTfulHTTP服務(wù)客戶端,內(nèi)置了Ribbon,用來(lái)做客戶端的負(fù)載均衡,去調(diào)用服務(wù)注冊(cè)中心的服務(wù)。但是有一個(gè)弊端,Feign不支持Spring MVC的注解,這在開(kāi)發(fā)中屬于比較麻煩的一點(diǎn),因?yàn)楹芏喙径际窃谟?span style="font-family: Calibri;">MVC

          于是OpenFeign誕生了,OpenFeignSpring Cloud Feign的基礎(chǔ)上支持了Spring MVC的注解,如@RequesMapping等等。

          OpenFeign的@FeignClient可以解析SpringMVC@RequestMapping注解下的接口,并通過(guò)動(dòng)態(tài)代理的方式產(chǎn)生實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)類(lèi)中做負(fù)載均衡并調(diào)用其他服務(wù)

          熔斷降級(jí)Hystrix

          到目前為止,我們的系統(tǒng)看起來(lái)可以正常的運(yùn)轉(zhuǎn)了,客戶端可以通過(guò)注冊(cè)中心get到服務(wù)端列表,通過(guò)負(fù)載均衡將請(qǐng)求平均的發(fā)放到服務(wù)端

          但是,但是,但是,網(wǎng)絡(luò)嗎,畢竟沒(méi)有百分百保證的事情,就像TCP的三次握手無(wú)法得到百分百的確定一樣,你確定經(jīng)過(guò)三次握手之后,客戶端和服務(wù)端就百分百的連接上了嗎

          在高并發(fā)的情況下,如果突然一個(gè)服務(wù)不可用了,或者說(shuō)服務(wù)響應(yīng)比較慢,可能導(dǎo)致所有的請(qǐng)求都會(huì)處于延遲,后續(xù)可能會(huì)因?yàn)槌瑫r(shí)報(bào)錯(cuò),如果一直這樣,會(huì)出現(xiàn)多次重試,多次重試就會(huì)導(dǎo)致線上的線程一直被占用,持續(xù)的請(qǐng)求打進(jìn)來(lái),就會(huì)直接把系統(tǒng)打崩

          于是針對(duì)這種問(wèn)題,就出現(xiàn)了一個(gè)對(duì)系統(tǒng)的保護(hù)機(jī)制,springcloud hystrix實(shí)現(xiàn)了斷路器、服務(wù)降級(jí)、線程隔離等多個(gè)保護(hù)系統(tǒng)的功能

          熔斷器hystrix的道理很簡(jiǎn)單,可以實(shí)現(xiàn)快速失敗?,F(xiàn)在家庭里面都有那種電力保護(hù)器,當(dāng)用電量超過(guò)一定的負(fù)載的時(shí)候,電力保護(hù)器會(huì)自動(dòng)切斷電源,來(lái)保護(hù)整個(gè)電路系統(tǒng)的運(yùn)轉(zhuǎn)。

          放在我們開(kāi)發(fā)的系統(tǒng)中來(lái),如果在一段時(shí)間內(nèi)偵測(cè)到很多同樣的錯(cuò)誤,就會(huì)認(rèn)為這個(gè)服務(wù)短時(shí)間不可用,不再訪問(wèn)遠(yuǎn)程服務(wù),直接返回失敗,使程序不影響后續(xù)的執(zhí)行,防止應(yīng)用程序不斷的重試,浪費(fèi)CPU和線程資源

          我們來(lái)看三個(gè)點(diǎn):斷路器、Fallback、資源隔離

          斷路器:這里有三個(gè)重要參數(shù),滑動(dòng)窗口大小20、熔斷開(kāi)關(guān)間隔5秒、錯(cuò)誤率50%,這三個(gè)參數(shù)也很好理解,每當(dāng)20個(gè)請(qǐng)求中,錯(cuò)誤率達(dá)到50%,斷路器則會(huì)切換到開(kāi)路狀態(tài),這時(shí)所有請(qǐng)求都直接失敗不會(huì)發(fā)送到后端服務(wù)。

          斷路器保持開(kāi)路狀態(tài)5秒之后,自動(dòng)切換到半開(kāi)路狀態(tài),此時(shí)斷路器嘗試放開(kāi)一個(gè)請(qǐng)求,看這個(gè)是否可以成功,如果請(qǐng)求成功,則斷路器切換回閉路狀態(tài),即正常訪問(wèn)服務(wù)。失敗則重新切換到開(kāi)路狀態(tài)

          Fallback:Fallback相當(dāng)于是降級(jí)操作,對(duì)于查詢操作,我們可以實(shí)現(xiàn)一個(gè)fallback方法, 當(dāng)請(qǐng)求后端服務(wù)出現(xiàn)異常的時(shí)候, 可以使用fallback方法返回的值,fallback方法的返回值一般是設(shè)置的默認(rèn)值或者來(lái)自緩存

          資源隔離:為每一個(gè)服務(wù)提供一個(gè)線程池來(lái)實(shí)現(xiàn)資源隔離,這樣做的優(yōu)點(diǎn)顯而易見(jiàn),就是運(yùn)行環(huán)境被隔離開(kāi)了,如果某個(gè)服務(wù)出現(xiàn)異常,不會(huì)影響到其它服務(wù)的運(yùn)行,但是帶來(lái)的代價(jià)就是維護(hù)多個(gè)線程池會(huì)對(duì)系統(tǒng)帶來(lái)額外的性能開(kāi)銷(xiāo)

          當(dāng)然,還可以配置Hystrix儀表盤(pán),它主要用來(lái)實(shí)時(shí)監(jiān)控Hystrix的各項(xiàng)指標(biāo)信息。通過(guò)Hystrix Dashboard反饋的實(shí)時(shí)信息,可以幫助我們快速發(fā)現(xiàn)系統(tǒng)中存在的問(wèn)題,從而及時(shí)地采取應(yīng)對(duì)措施。

          題外話:艙壁模式,隔離了每個(gè)工作負(fù)載或服務(wù)的關(guān)鍵資源,如連接池、內(nèi)存和 CPU。使用艙壁避免了單個(gè)工作負(fù)載(或服務(wù))消耗掉所有資源,從而導(dǎo)致其他服務(wù)出現(xiàn)故障的場(chǎng)景。這種模式主要是通過(guò)防止由一個(gè)服務(wù)引起的級(jí)聯(lián)故障來(lái)增加系統(tǒng)的彈性。

          這里的資源隔離就是使用的艙壁模式,熟悉Docker的應(yīng)該知道這么模式,Docker就是通過(guò)艙壁模式實(shí)現(xiàn)進(jìn)程的管理的,使得容器和容器之間相互隔離

          網(wǎng)關(guān)

          在上面我們學(xué)習(xí)了 Eureka 之后我們知道了服務(wù)提供者是消費(fèi)者通過(guò)Eureka進(jìn)行訪問(wèn)的,即Server是服務(wù)提供者的統(tǒng)一入口。那么整個(gè)應(yīng)用中存在那么多消費(fèi)者需要用戶進(jìn)行調(diào)用,這個(gè)時(shí)候用戶該怎樣訪問(wèn)這些消費(fèi)者工程呢?

          當(dāng)然可以像之前那樣直接訪問(wèn)這些工程。但這種方式?jīng)]有統(tǒng)一的消費(fèi)者工程調(diào)用入口,不便于訪問(wèn)與管理,而 Zuul 就是這樣的一個(gè)對(duì)于消費(fèi)者的統(tǒng)一入口。

          對(duì)外提供接口就會(huì)涉及到相應(yīng)的路由規(guī)則、校驗(yàn)和鑒權(quán)這些功能了,你想啊,支付模塊的支付服務(wù)那不得登錄之后才能調(diào)用了嗎,這里要是不校驗(yàn)用戶的登錄狀態(tài),豈不問(wèn)題大了

          簡(jiǎn)單來(lái)講網(wǎng)關(guān)是系統(tǒng)唯一對(duì)外的入口,介于客戶端與服務(wù)器端之間,用于對(duì)請(qǐng)求進(jìn)行鑒權(quán)、限流、路由、監(jiān)控等功能

          了解zuul和Gateway

          Filter是Zuul的核心,用來(lái)實(shí)現(xiàn)對(duì)外服務(wù)的控制。

          Filter的生命周期有4個(gè),分別是“PRE”、“ROUTING”、“POST”、“ERROR”,整個(gè)生命周期可以用下圖來(lái)表示。

          Zuul大部分功能都是通過(guò)過(guò)濾器來(lái)實(shí)現(xiàn)的,這些過(guò)濾器類(lèi)型對(duì)應(yīng)于請(qǐng)求的典型生命周期。

          • PRE:這種過(guò)濾器在請(qǐng)求被路由之前調(diào)用。我們可利用這種過(guò)濾器實(shí)現(xiàn)身份驗(yàn)證、在集群中選擇請(qǐng)求的微服務(wù)、記錄調(diào)試信息等。

          • ROUTING:這種過(guò)濾器將請(qǐng)求路由到微服務(wù)。這種過(guò)濾器用于構(gòu)建發(fā)送給微服務(wù)的請(qǐng)求,并使用Apache HttpClientNetfilx Ribbon請(qǐng)求微服務(wù)。

          • POST:這種過(guò)濾器在路由到微服務(wù)以后執(zhí)行。這種過(guò)濾器可用來(lái)為響應(yīng)添加標(biāo)準(zhǔn)的HTTP Header、收集統(tǒng)計(jì)信息和指標(biāo)、將響應(yīng)從微服務(wù)發(fā)送給客戶端等。

          • ERROR:在其他階段發(fā)生錯(cuò)誤時(shí)執(zhí)行該過(guò)濾器。除了默認(rèn)的過(guò)濾器類(lèi)型,Zuul還允許我們創(chuàng)建自定義的過(guò)濾器類(lèi)型。例如,我們可以定制一種STATIC類(lèi)型的過(guò)濾器,直接在Zuul中生成響應(yīng),而不將請(qǐng)求轉(zhuǎn)發(fā)到后端的微服務(wù)。

          Gateway:Spring Cloud Gateway 是 Spring Cloud 的一個(gè)全新項(xiàng)目,它旨在為微服務(wù)架構(gòu)提供一種簡(jiǎn)單有效的統(tǒng)一的 API 路由管理方式,目標(biāo)是替代 Netflix Zuul,其不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全,監(jiān)控/指標(biāo),和限流。

          zuul和Gateway的異同點(diǎn)

          • 底層都是servlet,都是屬于web網(wǎng)關(guān),處理HTTP請(qǐng)求

          • zuul僅支持同步,gateway支持異步,理論上gateway更能提高系統(tǒng)的吞吐量

          • gateway對(duì)比zuul多依賴了spring-webflux,在spring的支持下,功能更強(qiáng)大,內(nèi)部實(shí)現(xiàn)了限流、負(fù)載均衡等,擴(kuò)展性也更強(qiáng),但同時(shí)也限制了僅適合于Spring Cloud套件,zuul則可以擴(kuò)展至其他微服務(wù)框架中,其內(nèi)部沒(méi)有實(shí)現(xiàn)限流、負(fù)載均衡等。

          配置中心config

          當(dāng)我們的系統(tǒng)變得越來(lái)越龐大的時(shí)候,每個(gè)微服務(wù)都有屬于自己的配置文件,如果我們需要修改某些服務(wù)的配置,就需要找到這個(gè)服務(wù)的配置修改,并且重啟該服務(wù)才可以生效,這樣管理起來(lái)比較麻煩

          那么有沒(méi)有一種方法既能對(duì)配置文件統(tǒng)一地進(jìn)行管理,又能在項(xiàng)目運(yùn)行時(shí)動(dòng)態(tài)修改配置文件呢?

          你想一下,我們的應(yīng)用是不是只有啟動(dòng)的時(shí)候才會(huì)進(jìn)行配置文件的加載,那么我們的Spring Cloud Config就暴露出一個(gè)接口給啟動(dòng)應(yīng)用來(lái)獲取它所想要的配置文件,應(yīng)用獲取到配置文件然后再進(jìn)行它的初始化工作。

          看一下config的架構(gòu)


          等同于是把多個(gè)服務(wù)的配置文件集中起來(lái)管理。此時(shí)你肯定會(huì)有一個(gè)疑問(wèn),如果我在遠(yuǎn)程倉(cāng)庫(kù)修改了生產(chǎn)的配置文件,那對(duì)應(yīng)的引用會(huì)不會(huì)隨之立即生效呢,實(shí)現(xiàn)動(dòng)態(tài)的配置嗎

          答案是不能!

          啊呸,你上面不是說(shuō)可以在項(xiàng)目運(yùn)行的時(shí)候可以動(dòng)態(tài)修改配置文件,你現(xiàn)在又告訴我不能,你這不是在浪費(fèi)我的青春?jiǎn)?/span>

          別急,既然我說(shuō)了,那自然是有解決辦法,springcloud bus就閃亮登場(chǎng)了

          我們一般會(huì)使用Bus消息總線 +Spring Cloud Config進(jìn)行配置的動(dòng)態(tài)刷新。可以簡(jiǎn)單理解為Spring Cloud Bus的作用就是管理和廣播分布式系統(tǒng)中的消息,也就是常說(shuō)的廣播模式。

          擁有了Spring Cloud Bus之后,我們只需要?jiǎng)?chuàng)建一個(gè)簡(jiǎn)單的請(qǐng)求,并且加上@ResfreshScope注解就能進(jìn)行配置的動(dòng)態(tài)修改了

          總結(jié)一下

          這篇文章中我?guī)Т蠹页醪搅私饬薙pring Cloud的各個(gè)組件,他們有

          • Eureka 服務(wù)發(fā)現(xiàn)框架

          • Ribbon 進(jìn)程內(nèi)負(fù)載均衡器

          • Open Feign 服務(wù)調(diào)用映射

          • Hystrix 服務(wù)降級(jí)熔斷器

          • Zuul 微服務(wù)網(wǎng)關(guān)

          • Config 微服務(wù)統(tǒng)一配置中心

          • Bus 消息總線

          這個(gè)時(shí)候我再把開(kāi)頭的圖給大家扔過(guò)來(lái),大家看的是不是更清楚了,是不是感覺(jué)每個(gè)組件的作用都了然于心,證明你對(duì)微服務(wù)的架構(gòu)有了一定的了解了

          同時(shí),也證明你從這篇文章中收獲到了一些東西(暗示.jpg)

          結(jié)束語(yǔ)



          船長(zhǎng)希望有一天能夠靠寫(xiě)作養(yǎng)活自己,現(xiàn)在還在磨練,這個(gè)時(shí)間可能會(huì)持續(xù)很久,但是,請(qǐng)看我漂亮的堅(jiān)持


          感謝大家能夠做我最初的讀者和傳播者,請(qǐng)大家相信,只要你給我一份愛(ài),我終究會(huì)還你們一頁(yè)情的。


          船長(zhǎng)會(huì)持續(xù)更新技術(shù)文章,和生活中的暴躁文章,歡迎大家關(guān)注【Java賊船】,成為船長(zhǎng)的學(xué)習(xí)小伙伴,和船長(zhǎng)一起乘千里風(fēng)、破萬(wàn)里浪


          哦對(duì)了,后續(xù)所有的遠(yuǎn)程文章都會(huì)更新到這里


          https://github.com/DayuMM2021/Java



          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色在线看 | 一级免费观看 | 日本亚洲中文字幕 | 台湾成人在线视频 | 免费黄v在线播放 |