SpringCloud入門

鏈接:https://www.zhihu.com/question/283286745/answer/763040709

著作權(quán)歸作者所有陨界。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)议蟆,非商業(yè)轉(zhuǎn)載請注明出處菱属。

SpringCloud GitHub Demo(看完文章的同學可以自己練手玩玩):

https://github.com/ZhongFuCheng3y/msc-Demo

項目結(jié)構(gòu)圖:

二、集群/分布式/微服務(wù)/SOA是什么担巩?

像我這種技術(shù)小白讨衣,看到這些詞(集群/分布式/微服務(wù)/SOA)的時候换棚,感覺就是遙不可及的(高大尚的技術(shù)!反镇!)固蚤。就好像剛學Java面向?qū)ο蟮臅r候,在論壇上翻閱資料的時候歹茶,無意看到"面向切面編程"夕玩,也認為這是遙不可及的(高大尚的技術(shù)!惊豺!)风秤。

但真正接觸到"面向切面編程"的時候,發(fā)現(xiàn)原來就是如此啊扮叨,也沒什么大不了的。只不過當時被它的名字給唬住了...

不知道各位在剛接觸這些名字集群/分布式/微服務(wù)/SOA的時候领迈,有沒有被唬住了呢彻磁??

下面我就簡單說說這些名詞的意思

2.1什么是集群

以下內(nèi)容來源維基百科:

計算機集群簡稱集群是一種計算機系統(tǒng)狸捅,它通過一組松散集成的計算機軟件和/或硬件連接起來高度緊密地協(xié)作完成計算工作衷蜓。在某種意義上,他們可以被看作是一臺計算機尘喝。集群系統(tǒng)中的單個計算機通常稱為節(jié)點磁浇,通常通過局域網(wǎng)連接,但也有其它的可能連接方式朽褪。集群計算機通常用來改進單個計算機的計算速度和/或可靠性置吓。一般情況下集群計算機比單個計算機,比如工作站或超級計算機性能價格比要高得多

集群技術(shù)特點:

通過多臺計算機完成同一個工作缔赠,達到更高的效率衍锚。

兩機或多機內(nèi)容、工作過程等完全一樣嗤堰。如果一臺死機戴质,另一臺可以起作用。

在維基百科上說得也挺明白的了,我來舉個例子吧告匠。

小周在公司寫Java程序戈抄,但公司業(yè)務(wù)在發(fā)展,一個Java開發(fā)者可能忙不過來后专,小周有的時候也得請個假呀划鸽。于是請了3y過去一起做Java開發(fā)。平時小周和3y就寫Java程序行贪,但3y可能有事要回學校一趟漾稀。沒事,公司還有小周做Java開發(fā)呢建瘫,公司開發(fā)還能繼續(xù)運作崭捍。

3y跟小周都是做Java開發(fā)

3y來了啰脚,小周的工作可以分擔一些殷蛇。

3y請假了,還有小周在呢橄浓。

我寫了一個910便利網(wǎng)發(fā)布到服務(wù)器去了粒梦,現(xiàn)在越來越多的人訪問了,訪問有點慢荸实,怎么辦匀们??准给?很簡單泄朴,(只有充錢才能變強),加配置吧(加cpu露氮,加內(nèi)存)祖灰。升級完配置之后,訪問人數(shù)越來越多畔规,于是發(fā)現(xiàn)又不禁用啦局扶,在這臺機器上加配置已經(jīng)解決不了了,怎么辦叁扫?三妈??很簡單莫绣,(只有充錢才能變強)沈跨,我再買一臺服務(wù)器,將910便利網(wǎng)也發(fā)布到新買的這臺服務(wù)器上去兔综。

特點:

這兩臺服務(wù)器都是運行同一個系統(tǒng)--->910便利網(wǎng)

好處:

本來只有一臺機器處理訪問饿凛,現(xiàn)在有兩臺機器處理訪問了狞玛,分擔了壓力

如果其中一臺忘記繳費了涧窒,暫時用不了了心肪。沒關(guān)系,還有另一臺可以用呢纠吴。

集群:同一個業(yè)務(wù)硬鞍,部署在多個服務(wù)器上(不同的服務(wù)器運行同樣的代碼,干同一件事)

2.2什么是分布式

以下內(nèi)容來源維基百科:

分布式系統(tǒng)是一組計算機戴已,通過網(wǎng)絡(luò)相互連接傳遞消息與通信后并協(xié)調(diào)它們的行為而形成的系統(tǒng)固该。組件之間彼此進行交互以實現(xiàn)一個共同的目標

我也來舉個例子來說明一下吧:

現(xiàn)在公司有小周和3y一起做Java開發(fā)糖儡,做Java開發(fā)一般jQuery伐坏,AJAX都能寫一點,所以這些活都由我們來干握联“裆唬可是呢贡羔,3y對前端不是很熟沉颂,有的時候調(diào)試半天都調(diào)不出來促脉。老板認為3y是真的菜!于是讓小周專門來處理前端的事情代芜。這樣3y就高興了埠褪,可以專心寫自己的Java,前端就專門交由小周負責了挤庇。于是组橄,小周和3y就變成了協(xié)作開發(fā)

3y對前端不熟(能寫出來)罚随,但在調(diào)試的時候可能會花費很多時間

小周來專門做前端的事,3y可以專心寫自己的Java程序了羽资。

都是為了項目正常運行以及迭代淘菩。

我的910便利網(wǎng)已經(jīng)部署到兩臺服務(wù)器去了,但是越來越多的人去訪問⊥郎現(xiàn)在也逐漸承受不住啦潮改。那現(xiàn)在怎么辦啊腹暖?汇在?那繼續(xù)充錢變強?脏答?作為一個理智的我糕殉,肯定得想想是哪里有問題∧豆恚現(xiàn)在910便利網(wǎng)的模塊有好幾個,全都丟在同一個Tomcat里邊阿蝶。

其實有些模塊的訪問是很低的(比如后臺管理)雳锋,那我可不可以這樣做:將每個模塊抽取獨立出來,訪問量大的模塊用好的服務(wù)器裝著羡洁,沒啥人訪問的模塊用差的服務(wù)器裝著玷过。這樣的好處是:一、資源合理利用了(沒人訪問的模塊用性能差的服務(wù)器筑煮,訪問量大的模塊單獨提升性能就好了)辛蚊。二、耦合度降低了:每個模塊獨立出來真仲,各干各的事(專業(yè)的人做專業(yè)的事)袋马,便于擴展

特點:

將910便利網(wǎng)的功能拆分,模塊之間獨立袒餐,在使用的時候再將這些獨立的模塊組合起來就是一個系統(tǒng)了飞蛹。

好處:

模塊之間獨立,各做各的事灸眼,便于擴展卧檐,復用性高

高吞吐量。某個任務(wù)需要一個機器運行10個小時焰宣,將該任務(wù)用10臺機器的分布式跑(將這個任務(wù)拆分成10個小任務(wù))霉囚,可能2個小時就跑完了

分布式:一個業(yè)務(wù)分拆多個子業(yè)務(wù),部署在不同的服務(wù)器上(不同的服務(wù)器匕积,運行不同的代碼盈罐,為了同一個目的)

2.3集群/分布式

集群和分布式并不沖突,可以有分布式集群

現(xiàn)在3y的公司規(guī)模變大了闪唆,有5個小伙子寫Java盅粪,4個小伙子寫前端,2個小伙子做測試悄蕾,1個小伙子做DBA票顾。

Java,前端帆调,測試奠骄,DBA的關(guān)系看作是分布式的

5個Java看作是集群的(前端,測試同理)...

2.4分布式/微服務(wù)/SOA

其實我認為分布式/微服務(wù)/SOA這三個概念是差不多的番刊,了解了其中的一個含鳞,然后將自己的理解往上面套就好了。沒必要細分每個的具體概念~~(當然了芹务,我很期待有大佬可以在評論區(qū)留言說下自己的看法哈)

參考資料:

分布式與集群的區(qū)別是什么蝉绷?https://www.zhihu.com/question/20004877

分布式鸭廷、集群、微服務(wù)潜必、SOA 之間的區(qū)別https://blog.csdn.net/heatdeath/article/details/79038795

三靴姿、CAP理論

從上面所講的分布式概念我們已經(jīng)知道,分布式簡單理解就是:一個業(yè)務(wù)分拆多個子業(yè)務(wù)磁滚,部署在不同的服務(wù)器上

一般來說佛吓,一個子業(yè)務(wù)我們稱為節(jié)點

如果你接觸過一些分布式的基礎(chǔ)概念垂攘,那肯定會聽過CAP這個理論维雇。就比如說:你學了MySQL的InnoDB存儲引擎相關(guān)知識,你肯定聽過ACID晒他!

首先吱型,我們來看一下CAP分別代表的是什么意思:

C:數(shù)據(jù)一致性(consistency)

所有節(jié)點擁有數(shù)據(jù)的最新版本

A:可用性(availability)

數(shù)據(jù)具備高可用性

P:分區(qū)容錯性(partition-tolerance)

容忍網(wǎng)絡(luò)出現(xiàn)分區(qū),分區(qū)之間網(wǎng)絡(luò)不可達陨仅。

下面有三個節(jié)點(它們是集群的)津滞,此時三個節(jié)點都能夠相互通信:

由于我們的系統(tǒng)是分布式的,節(jié)點之間的通信是通過網(wǎng)絡(luò)來進行的灼伤。只要是分布式系統(tǒng)触徐,那很有可能會出現(xiàn)一種情況:因為一些故障,使得有些節(jié)點之間不連通了狐赡,整個網(wǎng)絡(luò)就分成了幾塊區(qū)域撞鹉。

數(shù)據(jù)就散布在了這些不連通的區(qū)域中,這就叫分區(qū)

現(xiàn)在出現(xiàn)了網(wǎng)絡(luò)分區(qū)后颖侄,此時有一個請求過來了鸟雏,想要注冊一個賬戶。

此時我們節(jié)點一和節(jié)點三是不可通信的览祖,這就有了抉擇:

如果允許當前用戶注冊一個賬戶孝鹊,此時注冊的記錄數(shù)據(jù)只會在節(jié)點一和節(jié)點二或者節(jié)點二和節(jié)點三同步,因為節(jié)點一和節(jié)點三的記錄不能同步的展蒂。

這種情況其實就是選擇了可用性(availability)又活,拋棄了數(shù)據(jù)一致性(consistency)

如果不允許當前用戶注冊一個賬戶(就是要等到節(jié)點一和節(jié)點三恢復通信)。節(jié)點一和節(jié)點三一旦恢復通信玄货,我們就可以保證節(jié)點擁有的數(shù)據(jù)是最新版本

這種情況其實就是拋棄了可用性(availability)悼泌,選擇了數(shù)據(jù)一致性(consistency)

3.1再次梳理一下CAP理論

一般我們說的分布式系統(tǒng)松捉,P:分區(qū)容錯性(partition-tolerance)這個是必需的,這是客觀存在的馆里。

CAP是無法完全兼顧的隘世,從上面的例子也可以看出可柿,我們可以選AP,也可以選CP丙者。但是复斥,要注意的是:不是說選了AP,C就完全拋棄了械媒。不是說選了CP目锭,A就完全拋棄了!

在CAP理論中纷捞,C所表示的一致性是強一致性(每個節(jié)點的數(shù)據(jù)都是最新版本)痢虹,其實一致性還有其他級別的:

弱一致性:弱一致性是相對于強一致性而言,它不保證總能得到最新的值主儡;

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

可用性的值域可以定義成0到100%的連續(xù)區(qū)間糜值。

所以丰捷,CAP理論定義的其實是在容忍網(wǎng)絡(luò)分區(qū)的條件下,“強一致性”和“極致可用性”無法同時達到寂汇。

參考資料:

CAP理論中的P到底是個什么意思病往?https://www.zhihu.com/question/54105974

淺談分布式系統(tǒng)的基本問題:可用性與一致性:https://m.aliyun.com/yunqi/articles/2709

分布式系統(tǒng)的CAP理論:http://www.hollischuang.com/archives/666

為什么CAP理論在舍棄P的情況下,可以有完美的CA健无?https://www.zhihu.com/question/285878189

不懂點CAP理論荣恐,你好意思說你是做分布式的嗎?http://www.yunweipai.com/archives/8432.html

擴展閱讀:

淺談分布式事務(wù):https://m.aliyun.com/yunqi/articles/230242

四累贤、SpringCloud就是這么簡單

相信大家讀到這里叠穆,對分布式/微服務(wù)已經(jīng)有一定的了解了,其實單從概念來說臼膏,是非常容易理解的硼被。只是很可能被它的名字給唬住了。

下面我就來講講SpringCloud最基礎(chǔ)的知識~

4.1為什么需要SpringCloud渗磅?

前面也講了嚷硫,從分布式/微服務(wù)的角度而言:就是把我們一的項目,分解成多個的模塊始鱼。這些小的模塊組合起來仔掸,完成功能。

舉個可能不太恰當?shù)睦?現(xiàn)實可能不會這么拆分医清,但意思到位就好了):

拆分出多個模塊以后起暮,就會出現(xiàn)各種各樣的問題,而SpringCloud提供了一整套的解決方案会烙!

注:這些模塊是獨立成一個子系統(tǒng)的(不同主機)负懦。

SpringCloud的基礎(chǔ)功能

服務(wù)治理: Spring Cloud Eureka

客戶端負載均衡: Spring Cloud Ribbon

服務(wù)容錯保護: Spring Cloud Hystrix

聲明式服務(wù)調(diào)用: Spring Cloud Feign

API網(wǎng)關(guān)服務(wù):Spring Cloud Zuul

分布式配置中心: Spring Cloud Config

SpringCloud的高級功能(本文不講):

消息總線: Spring Cloud Bus

消息驅(qū)動的微服務(wù): Spring Cloud Stream

分布式服務(wù)跟蹤: Spring Cloud Sleuth

五筒捺、引出Eureka

那會出現(xiàn)什么問題呢?纸厉?首當其沖的就是子系統(tǒng)之間的通訊問題系吭。子系統(tǒng)與子系統(tǒng)之間不是在同一個環(huán)境下,那就需要遠程調(diào)用颗品。遠程調(diào)用可能就會想到httpClient肯尺,WebService等等這些技術(shù)來實現(xiàn)。

既然是遠程調(diào)用抛猫,就必須知道ip地址蟆盹,我們可能有以下的場景。

功能實現(xiàn)一:A服務(wù)需要調(diào)用B服務(wù)

在A服務(wù)的代碼里面調(diào)用B服務(wù)闺金,顯式通過IP地址調(diào)用:http://123.123.123.123:8888/java3y/3

功能實現(xiàn)二:A服務(wù)調(diào)用B服務(wù)逾滥,B服務(wù)調(diào)用C服務(wù),C服務(wù)調(diào)用D服務(wù)

在A服務(wù)的代碼里面調(diào)用B服務(wù)败匹,顯式通過IP地址調(diào)用:http://123.123.123.123:8888/java3y/3寨昙,(同樣地)B->C,C->D

功能實現(xiàn)三:D服務(wù)調(diào)用B服務(wù)掀亩,B服務(wù)調(diào)用C服務(wù)

在D服務(wù)的代碼里面調(diào)用B服務(wù)舔哪,顯式通過IP地址調(diào)用:http://123.123.123.123:8888/java3y/3,(同樣地)B->C

.....等等等等

萬一槽棍,我們B服務(wù)的IP地址變了捉蚤,想想會出現(xiàn)什么問題:A服務(wù),D服務(wù)(等等)需要手動更新B服務(wù)的地址

在服務(wù)多的情況下,手動來維護這些靜態(tài)配置就是噩夢炼七!

為了解決微服務(wù)架構(gòu)中的服務(wù)實例維護問題(ip地址)缆巧, 產(chǎn)生了大量的服務(wù)治理框架和產(chǎn)品。 這些框架和產(chǎn)品的實現(xiàn)都圍繞著服務(wù)注冊與服務(wù)發(fā)現(xiàn)機制來完成對微服務(wù)應(yīng)用實例的自動化管理豌拙。

在SpringCloud中我們的服務(wù)治理框架一般使用的就是Eureka陕悬。

我們的問題:

現(xiàn)在有A、B按傅、C捉超、D四個服務(wù),它們之間會互相調(diào)用(而且IP地址很可能會發(fā)生變化)唯绍,一旦某個服務(wù)的IP地址變了拼岳,那服務(wù)中的代碼要跟著變,手動維護這些靜態(tài)配置(IP)非常麻煩况芒!

Eureka是這樣解決上面所說的情況的:

創(chuàng)建一個E服務(wù)惜纸,將A、B、C堪簿、D四個服務(wù)的信息都注冊到E服務(wù)上,E服務(wù)維護這些已經(jīng)注冊進來的信息

A皮壁、B椭更、C、D四個服務(wù)都可以拿到Eureka(服務(wù)E)那份注冊清單蛾魄。A虑瀑、B、C滴须、D四個服務(wù)互相調(diào)用不再通過具體的IP地址舌狗,而是通過服務(wù)名來調(diào)用

拿到注冊清單--->注冊清單上有服務(wù)名--->自然就能夠拿到服務(wù)具體的位置了(IP)扔水。

其實簡單來說就是:代碼中通過服務(wù)名找到對應(yīng)的IP地址(IP地址會變痛侍,但服務(wù)名一般不會變)

5.1Eureka細節(jié)

Eureka專門用于給其他服務(wù)注冊的稱為Eureka Server(服務(wù)注冊中心),其余注冊到Eureka Server的服務(wù)稱為Eureka Client魔市。

在Eureka Server一般我們會這樣配置:

register-with-eureka: false? ? #false表示不向注冊中心注冊自己主届。

? ? fetch-registry: false? ? #false表示自己端就是注冊中心,我的職責就是維護服務(wù)實例待德,并不需要去檢索服務(wù)

Eureka Client分為服務(wù)提供者和服務(wù)消費者君丁。

但很可能,某服務(wù)既是服務(wù)提供者又是服務(wù)消費者将宪。

如果在網(wǎng)上看到SpringCloud的某個服務(wù)配置沒有"注冊"到Eureka-Server也不用過于驚訝(但是它是可以獲取Eureka服務(wù)清單的)

很可能只是作者把該服務(wù)認作為單純的服務(wù)消費者绘闷,單純的服務(wù)消費者無需對外提供服務(wù),也就無須注冊到Eureka中了

eureka:

? client:

? ? register-with-eureka: false? # 當前微服務(wù)不注冊到eureka中(消費端)

? ? service-url:

? ? ? defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

下面是Eureka的治理機制:

服務(wù)提供者

服務(wù)注冊:啟動的時候會通過發(fā)送REST請求的方式將自己注冊到Eureka Server上较坛,同時帶上了自身服務(wù)的一些元數(shù)據(jù)信息印蔗。

**服務(wù)續(xù)約:**在注冊完服務(wù)之后,服務(wù)提供者會維護一個心跳用來持續(xù)告訴Eureka Server: "我還活著 ” 燎潮、

服務(wù)下線:當服務(wù)實例進行正常的關(guān)閉操作時喻鳄,它會觸發(fā)一個服務(wù)下線的REST請求給Eureka Server, 告訴服務(wù)注冊中心:“我要下線了 ”。

服務(wù)消費者

獲取服務(wù):當我們啟動服務(wù)消費者的時候确封,它會發(fā)送一個REST請求給服務(wù)注冊中心除呵,來獲取上面注冊的服務(wù)清單

服務(wù)調(diào)用:服務(wù)消費者在獲取服務(wù)清單后,通過服務(wù)名可以獲得具體提供服務(wù)的實例名和該實例的元數(shù)據(jù)信息爪喘。在進行服務(wù)調(diào)用的時候颜曾,優(yōu)先訪問同處一個Zone中的服務(wù)提供方

Eureka Server(服務(wù)注冊中心):

失效剔除:默認每隔一段時間(默認為60秒) 將當前清單中超時(默認為90秒)沒有續(xù)約的服務(wù)剔除出去秉剑。

自我保護:泛豪。EurekaServer 在運行期間,會統(tǒng)計心跳失敗的比例在15分鐘之內(nèi)是否低于85%(通常由于網(wǎng)絡(luò)不穩(wěn)定導致)。 Eureka Server會將當前的實例注冊信息保護起來诡曙, 讓這些實例不會過期臀叙,盡可能保護這些注冊信息

最后价卤,我們就有了這張圖:

舉個例子:

3y跟女朋友去東站的東方寶泰逛街劝萤,但不知道東方寶泰有什么好玩的。于是就去物業(yè)搜了一下東方寶泰商戶清單慎璧,發(fā)現(xiàn)一樓有優(yōu)衣庫床嫌,二樓有星巴克,三樓有麥當勞胸私。

在優(yōu)衣庫旁邊厌处,有新開張的KFC,在墻壁打上了很大的標識“歡迎KFC入駐東方寶泰”岁疼。

商家們需要定時交物業(yè)費給物業(yè)阔涉。

物業(yè)維持東方寶泰的穩(wěn)定性。如果某個商家不想在東方寶泰運營了捷绒,告訴了物業(yè)洒敏。物業(yè)自然就會將其在東方寶泰商戶清單去除。

優(yōu)秀博文:

Spring Cloud Eureka詳解:https://blog.csdn.net/sunhuiliang85/article/details/76222517

《Spring Cloud Netflix》 -- 服務(wù)注冊和服務(wù)發(fā)現(xiàn)-Eureka 的使用:https://zhuanlan.zhihu.com/p/26472547

微服務(wù)架構(gòu):Eureka參數(shù)配置項詳解:https://www.cnblogs.com/fangfuhai/p/7070325.html

六疙驾、引出RestTemplate和Ribbon

通過Eureka服務(wù)治理框架凶伙,我們可以通過服務(wù)名來獲取具體的服務(wù)實例的位置了(IP)。一般在使用SpringCloud的時候不需要自己手動創(chuàng)建HttpClient來進行遠程調(diào)用它碎。

可以使用Spring封裝好的RestTemplate工具類函荣,使用起來很簡單:

// 傳統(tǒng)的方式,直接顯示寫死IP是不好的扳肛!

? ? //private static final String REST_URL_PREFIX = "http://localhost:8001";

// 服務(wù)實例名

? ? private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

? ? /**

? ? * 使用 使用restTemplate訪問restful接口非常的簡單粗暴無腦傻挂。 (url, requestMap,

? ? * ResponseBean.class)這三個參數(shù)分別代表 REST請求地址、請求參數(shù)挖息、HTTP響應(yīng)轉(zhuǎn)換被轉(zhuǎn)換成的對象類型金拒。

? ? */

? ? @Autowired

? ? private RestTemplate restTemplate;

? ? @RequestMapping(value = "/consumer/dept/add")

? ? public boolean add(Dept dept) {

? ? ? ? return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);

? ? }

為了實現(xiàn)服務(wù)的高可用,我們可以將服務(wù)提供者集群套腹。比如說绪抛,現(xiàn)在一個秒殺系統(tǒng)設(shè)計出來了,準備上線了电禀。在11月11號時為了能夠支持高并發(fā)幢码,我們開多臺機器來支持并發(fā)量。

現(xiàn)在想要這三個秒殺系統(tǒng)合理攤分用戶的請求(專業(yè)來說就是負載均衡)尖飞,可能你會想到nginx症副。

其實SpringCloud也支持的負載均衡功能店雅,只不過它是客戶端的負載均衡,這個功能實現(xiàn)就是Ribbon贞铣!

負載均衡又區(qū)分了兩種類型:

客戶端負載均衡(Ribbon)

服務(wù)實例的清單在客戶端闹啦,客戶端進行負載均衡算法分配。

(從上面的知識我們已經(jīng)知道了:客戶端可以從Eureka Server中得到一份服務(wù)清單辕坝,在發(fā)送請求時通過負載均衡算法亥揖,在多個服務(wù)器之間選擇一個進行訪問)

服務(wù)端負載均衡(Nginx)

服務(wù)實例的清單在服務(wù)端,服務(wù)器進行負載均衡算法分配

所以圣勒,我們的圖可以畫成這樣:

6.1Ribbon細節(jié)

Ribbon是支持負載均衡,默認的負載均衡策略是輪詢摧扇,我們也是可以根據(jù)自己實際的需求自定義負載均衡策略的圣贸。

@Configuration

public class MySelfRule

{

@Bean

public IRule myRule()

{

//return new RandomRule();// Ribbon默認是輪詢,我自定義為隨機

//return new RoundRobinRule();// Ribbon默認是輪詢扛稽,我自定義為隨機

return new RandomRule_ZY();// 我自定義為每臺機器5次

}

}

實現(xiàn)起來也很簡單:繼承AbstractLoadBalancerRule類吁峻,重寫public Server choose(ILoadBalancer lb, Object key)即可。

SpringCloud 在CAP理論是選擇了AP的在张,在Ribbon中還可以配置重試機制的(有興趣的同學可以去搜搜)~

舉個例子:

3y跟女朋友過了幾個月用含,又去東方寶泰了。由于記性不好帮匾,又去物業(yè)那弄了一份東方寶泰商戶清單啄骇。

這次看到東方寶泰又開了一間麥當勞,一間在二樓瘟斜,一間在三樓缸夹。原來生意太好了,為了能提高用戶體驗螺句,在二樓多開了一間麥當勞虽惭。

這時,3y問女朋友:“去哪間麥當勞比較好蛇尚?要不我們拋硬幣決定芽唇?”3y女朋友說:”你是不是傻,肯定哪間近去哪間啊“

優(yōu)秀博文:

擼一擼Spring Cloud Ribbon的原理-負載均衡策略:https://www.cnblogs.com/kongxianghai/p/8477781.html

七取劫、引出Hystrix

到目前為止匆笤,我們的服務(wù)看起來好像挺好的了:能夠根據(jù)服務(wù)名來遠程調(diào)用其他的服務(wù),可以實現(xiàn)客戶端的負載均衡谱邪。

但是疚膊,如果我們在調(diào)用多個遠程服務(wù)時,某個服務(wù)出現(xiàn)延遲虾标,會怎么樣寓盗?灌砖?

高并發(fā)的情況下,由于單個服務(wù)的延遲傀蚌,可能導致所有的請求都處于延遲狀態(tài)基显,甚至在幾秒鐘就使服務(wù)處于負載飽和的狀態(tài),資源耗盡善炫,直到不可用撩幽,最終導致這個分布式系統(tǒng)都不可用,這就是“雪崩”箩艺。

針對上述問題窜醉, Spring Cloud Hystrix實現(xiàn)了斷路器、線程隔離等一系列服務(wù)保護功能艺谆。

Fallback(失敗快速返回):當某個服務(wù)單元發(fā)生故障(類似用電器發(fā)生短路)之后榨惰,通過斷路器的故障監(jiān)控(類似熔斷保險絲),向調(diào)用方返回一個錯誤響應(yīng)静汤, 而不是長時間的等待琅催。這樣就不會使得線程因調(diào)用故障服務(wù)被長時間占用不釋放,避免了故障在分布式系統(tǒng)中的蔓延虫给。

資源/依賴隔離(線程池隔離):它會為每一個依賴服務(wù)創(chuàng)建一個獨立的線程池藤抡,這樣就算某個依賴服務(wù)出現(xiàn)延遲過高的情況,也只是對該依賴服務(wù)的調(diào)用產(chǎn)生影響抹估, 而不會拖慢其他的依賴服務(wù)缠黍。

Hystrix提供幾個熔斷關(guān)鍵參數(shù):滑動窗口大小(20)药蜻、 熔斷器開關(guān)間隔(5s)嫁佳、錯誤率(50%)

每當20個請求中,有50%失敗時谷暮,熔斷器就會打開蒿往,此時再調(diào)用此服務(wù),將會直接返回失敗湿弦,不再調(diào)遠程服務(wù)瓤漏。

直到5s鐘之后,重新檢測該觸發(fā)條件颊埃,判斷是否把熔斷器關(guān)閉蔬充,或者繼續(xù)打開

Hystrix還有請求合并班利、請求緩存這樣強大的功能饥漫,在此我就不具體說明了,有興趣的同學可繼續(xù)深入學習~

7.1Hystrix儀表盤

Hystrix儀表盤:它主要用來實時監(jiān)控Hystrix的各項指標信息罗标。通過Hystrix Dashboard反饋的實時信息庸队,可以幫助我們快速發(fā)現(xiàn)系統(tǒng)中存在的問題积蜻,從而及時地采取應(yīng)對措施。

啟動時的頁面:

監(jiān)控單服務(wù)的頁面:

我們現(xiàn)在的服務(wù)是這樣的:

除了可以開啟單個實例的監(jiān)控頁面之外彻消,還有一個監(jiān)控端點/turbine.stream是對集群使用的竿拆。 從端點的命名中,可以引入Turbine, 通過它來匯集監(jiān)控信息宾尚,并將聚合后的信息提供給 HystrixDashboard 來集中展示和監(jiān)控丙笋。

舉個例子:

3y和女朋友決定去萬達玩,去到萬達的停車場發(fā)現(xiàn)在負一層已經(jīng)大大寫上“負一層已停滿煌贴,請下負二層御板,負二層空余停車位還有100個!”

這時牛郑,3y就跟女朋友說:“萬達停車場是做得挺好的怠肋,如果它沒有直接告知我負一層已滿,可能我就去負一層找位置了井濒,要是一堆人跑去負一層但都找不到車位的話,恐怕就塞死了”列林。3y接著說:“看停車位的狀態(tài)也做得不錯瑞你,在停車位上頭有一個感應(yīng)(監(jiān)控),如果是紅色就代表已被停了希痴,如果是綠色就說明停車位是空的”者甲。

3y女朋友不屑的說:“你話是真的多”

參考資料:

Hystrix ,為什么說它是每個系統(tǒng)不可或缺的開源框架砌创?https://zhuanlan.zhihu.com/p/34304136

深入理解Hystrix之文檔翻譯:https://zhuanlan.zhihu.com/p/28523060

談?wù)勎覍Ψ?wù)熔斷虏缸、服務(wù)降級的理解:https://blog.csdn.net/guwei9111986/article/details/51649240

Hystrix幾篇文章《青芒》:https://segmentfault.com/u/yedge/articles

八、引出Feign

上面已經(jīng)介紹了Ribbon和Hystrix了嫩实,可以發(fā)現(xiàn)的是:他倆作為基礎(chǔ)工具類框架廣泛地應(yīng)用在各個微服務(wù)的實現(xiàn)中刽辙。我們會發(fā)現(xiàn)對這兩個框架的使用幾乎是同時出現(xiàn)的。

為了簡化我們的開發(fā)甲献,Spring Cloud Feign出現(xiàn)了宰缤!它基于 Netflix Feign 實現(xiàn),整合了 Spring Cloud Ribbon 與 Spring Cloud Hystrix, 除了整合這兩者的強大功能之外晃洒,它還提 供了聲明式的服務(wù)調(diào)用(不再通過RestTemplate)慨灭。

Feign是一種聲明式、模板化的HTTP客戶端球及。在Spring Cloud中使用Feign, 我們可以做到使用HTTP請求遠程服務(wù)時能與調(diào)用本地方法一樣的編碼體驗氧骤,開發(fā)者完全感知不到這是遠程方法,更感知不到這是個HTTP請求吃引。

下面就簡單看看Feign是怎么優(yōu)雅地實現(xiàn)遠程調(diào)用的:

服務(wù)綁定:

// value --->指定調(diào)用哪個服務(wù)

// fallbackFactory--->熔斷器的降級提示

@FeignClient(value = "MICROSERVICECLOUD-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)

public interface DeptClientService {

? ? // 采用Feign我們可以使用SpringMVC的注解來對服務(wù)進行綁定筹陵!

? ? @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)

? ? public Dept get(@PathVariable("id") long id);

? ? @RequestMapping(value = "/dept/list", method = RequestMethod.GET)

? ? public List<Dept> list();

? ? @RequestMapping(value = "/dept/add", method = RequestMethod.POST)

? ? public boolean add(Dept dept);

}

Feign中使用熔斷器:

/**

* Feign中使用斷路器

* 這里主要是處理異常出錯的情況(降級/熔斷時服務(wù)不可用刽锤,fallback就會找到這里來)

*/

@Component // 不要忘記添加,不要忘記添加

public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {

? ? @Override

? ? public DeptClientService create(Throwable throwable) {

? ? ? ? return new DeptClientService() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public Dept get(long id) {

? ? ? ? ? ? ? ? return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有沒有對應(yīng)的信息,Consumer客戶端提供的降級信息,此刻服務(wù)Provider已經(jīng)關(guān)閉")

? ? ? ? ? ? ? ? ? ? ? ? .setDb_source("no this database in MySQL");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public List<Dept> list() {

? ? ? ? ? ? ? ? return null;

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean add(Dept dept) {

? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? }

? ? ? ? };

? ? }

}

調(diào)用:

九惶翻、引出Zuul

基于上面的學習姑蓝,我們現(xiàn)在的架構(gòu)很可能會設(shè)計成這樣:

這樣的架構(gòu)會有兩個比較麻煩的問題:

路由規(guī)則與服務(wù)實例的維護間題:外層的負載均衡(nginx)需要維護所有的服務(wù)實例清單(圖上的OpenService)

簽名校驗、 登錄校驗冗余問題:為了保證對外服務(wù)的安全性吕粗, 我們在服務(wù)端實現(xiàn)的微服務(wù)接口纺荧,往往都會有一定的權(quán)限校驗機制,但我們的服務(wù)是獨立的颅筋,我們不得不在這些應(yīng)用中都實現(xiàn)這樣一套校驗邏輯宙暇,這就會造成校驗邏輯的冗余。

還是畫個圖來理解一下吧:

每個服務(wù)都有自己的IP地址议泵,Nginx想要正確請求轉(zhuǎn)發(fā)到服務(wù)上占贫,就必須維護著每個服務(wù)實例的地址

更是災難的是:這些服務(wù)實例的IP地址還有可能會變先口,服務(wù)之間的劃分也很可能會變型奥。

http://123.123.123.123

http://123.123.123.124

http://123.123.123.125

http://123.123.123.126

http://123.123.123.127

購物車和訂單模塊都需要用戶登錄了才可以正常訪問,基于現(xiàn)在的架構(gòu)碉京,只能在購物車和訂單模塊都編寫校驗邏輯厢汹,這無疑是冗余的代碼。

為了解決上面這些常見的架構(gòu)問題谐宙,API網(wǎng)關(guān)的概念應(yīng)運而生烫葬。在SpringCloud中了提供了基于Netfl ix Zuul實現(xiàn)的API網(wǎng)關(guān)組件Spring Cloud Zuul

Spring Cloud Zuul是這樣解決上述兩個問題的:

SpringCloud Zuul通過與SpringCloud Eureka進行整合凡蜻,將自身注冊為Eureka服務(wù)治理下的應(yīng)用搭综,同時從Eureka中獲得了所有其他微服務(wù)的實例信息。外層調(diào)用都必須通過API網(wǎng)關(guān)划栓,使得將維護服務(wù)實例的工作交給了服務(wù)治理框架自動完成兑巾。

在API網(wǎng)關(guān)服務(wù)上進行統(tǒng)一調(diào)用來對微服務(wù)接口做前置過濾,以實現(xiàn)對微服務(wù)接口的攔截和校驗

Zuul天生就擁有線程隔離和斷路器的自我保護功能,以及對服務(wù)調(diào)用的客戶端負載均衡功能致盟。也就是說:Zuul也是支持Hystrix和Ribbon糜颠。

關(guān)于Zuul還有很多知識點(由于篇幅問題,這里我就不細說了):

路由匹配(動態(tài)路由)

過濾器實現(xiàn)(動態(tài)過濾器)

默認會過濾掉Cookie與敏感的HTTP頭信息(額外配置)

9.1可能對Zuul的疑問

Zuul支持Ribbon和Hystrix,也能夠?qū)崿F(xiàn)客戶端的負載均衡。我們的Feign不也是實現(xiàn)客戶端的負載均衡和Hystrix的嗎?既然Zuul已經(jīng)能夠?qū)崿F(xiàn)了称诗,那我們的Feign還有必要嗎?

或者可以這樣理解:

zuul是對外暴露的唯一接口相當于路由的是controller的請求头遭,而Ribbonhe和Fegin路由了service的請求

zuul做最外層請求的負載均衡 寓免,而Ribbon和Fegin做的是系統(tǒng)內(nèi)部各個微服務(wù)的service的調(diào)用的負載均衡

有了Zuul癣诱,還需要Nginx嗎?他倆可以一起使用嗎袜香?

我的理解:Zuul和Nginx是可以一起使用的(畢竟我們的Zuul也是可以搭成集群來實現(xiàn)高可用的)撕予,要不要一起使用得看架構(gòu)的復雜度了(業(yè)務(wù))~~~

參考資料:

微服務(wù)與API網(wǎng)關(guān)(上): 為什么需要API網(wǎng)關(guān)?:http://blog.didispace.com/hzf-ms-apigateway-1/

談?wù)?API 網(wǎng)關(guān):http://www.reibang.com/p/b52a2773e75f

談?wù)勎⒎?wù)中的 API 網(wǎng)關(guān)(API Gateway):https://www.cnblogs.com/savorboard/p/api-gateway.html

API網(wǎng)關(guān)性能比較:NGINX vs. ZUUL vs. Spring Cloud Gateway :http://www.360doc.com/content/18/0208/05/46368139_728502763.shtml

談API網(wǎng)關(guān)的背景蜈首、架構(gòu)以及落地方案:http://www.infoq.com/cn/news/2016/07/API-background-architecture-floo

zuul和nginx:https://zhuanlan.zhihu.com/p/37385481

十实抡、引出SpringCloud Config

隨著業(yè)務(wù)的擴展,我們的服務(wù)會越來越多欢策,越來越多吆寨。每個服務(wù)都有自己的配置文件。

既然是配置文件踩寇,給我們配置的東西啄清,那難免會有些改動的。

比如我們的Demo中俺孙,每個服務(wù)都寫上相同的配置文件辣卒。萬一我們有一天,配置文件中的密碼需要更換了睛榄,那就得三個都要重新更改荣茫。

在分布式系統(tǒng)中,某一個基礎(chǔ)服務(wù)信息變更懈费,都很可能會引起一系列的更新和重啟

Spring Cloud Config項目是一個解決分布式系統(tǒng)的配置管理方案计露。它包含了Client和Server兩個部分博脑,server提供配置文件的存儲憎乙、以接口的形式將配置文件的內(nèi)容提供出去,client通過接口獲取數(shù)據(jù)叉趣、并依據(jù)此數(shù)據(jù)初始化自己的應(yīng)用泞边。

簡單來說,使用Spring Cloud Config就是將配置文件放到統(tǒng)一的位置管理(比如GitHub)疗杉,客戶端通過接口去獲取這些配置文件阵谚。

在GitHub上修改了某個配置文件,應(yīng)用加載的就是修改后的配置文件烟具。

SpringCloud Config其他的知識:

在SpringCloud Config的服務(wù)端梢什, 對于配置倉庫的默認實現(xiàn)采用了Git,我們也可以配置SVN朝聋。

配置文件內(nèi)的信息加密和解密

修改了配置文件嗡午,希望不用重啟來動態(tài)刷新配置,配合Spring Cloud Bus 使用~

使用SpringCloud Config可能的疑問:application.yml和 bootstrap.yml區(qū)別

https://www.cnblogs.com/BlogNetSpace/p/8469033.html

總結(jié)

本文主要寫了SpringCloud的基礎(chǔ)知識冀痕,希望大家看完能有所幫助~

SpringCloud的資料也很多荔睹,我整理一些我認為比較好狸演,想要深入的同學不妨看看下邊的資源~~~

SpringCloud系列文章參考資料:

史上最簡單的 SpringCloud 教程 | 終章https://blog.csdn.net/forezp/article/details/70148833

Spring Cloud基礎(chǔ)教程《程序員DD》http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/

Spring Cloud 系列文章《純潔的微笑》:http://www.ityouknow.com/spring-cloud.html

SpringCloud系列文章:https://www.cnblogs.com/woshimrf/tag/SpringCloud/

SpringCloud系列文章《狂小白》:https://www.cnblogs.com/huangjuncong/tag/SpringCloud/

SpringCloud官方文檔:http://projects.spring.io/spring-cloud/

Spring Cloud 中文文檔:https://springcloud.cc/spring-cloud-dalston.html#_appendix_compendium_of_configuration_properties

參考書籍:

《SpringCloud 微服務(wù)實戰(zhàn)》

SpringCloud GitHub Demo(看完文章的同學可以自己練手玩玩,寫好了ReadMe了):

https://github.com/ZhongFuCheng3y/msc-Demo

涵蓋Java后端所有知識點的開源項目(已有5.8K star):https://github.com/ZhongFuCheng3y/3y

如果大家想要實時關(guān)注我更新的文章以及分享的干貨的話僻他,微信搜索Java3y

PDF文檔的內(nèi)容均為手打宵距,有任何的不懂都可以直接來問我(公眾號有我的聯(lián)系方式)。


收藏等于白嫖吨拗,點贊才是真情满哪!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丢胚,隨后出現(xiàn)的幾起案子翩瓜,更是在濱河造成了極大的恐慌,老刑警劉巖携龟,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兔跌,死亡現(xiàn)場離奇詭異,居然都是意外死亡峡蟋,警方通過查閱死者的電腦和手機坟桅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕊蝗,“玉大人仅乓,你說我怎么就攤上這事∨钇荩” “怎么了夸楣?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長子漩。 經(jīng)常有香客問我豫喧,道長,這世上最難降的妖魔是什么幢泼? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任紧显,我火速辦了婚禮,結(jié)果婚禮上缕棵,老公的妹妹穿的比我還像新娘孵班。我一直安慰自己,他們只是感情好招驴,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布篙程。 她就那樣靜靜地躺著,像睡著了一般别厘。 火紅的嫁衣襯著肌膚如雪虱饿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音郭厌,去河邊找鬼袋倔。 笑死,一個胖子當著我的面吹牛折柠,可吹牛的內(nèi)容都是我干的宾娜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扇售,長吁一口氣:“原來是場噩夢啊……” “哼前塔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起承冰,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤华弓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后困乒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寂屏,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年娜搂,在試婚紗的時候發(fā)現(xiàn)自己被綠了迁霎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡百宇,死狀恐怖考廉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情携御,我是刑警寧澤昌粤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站啄刹,受9級特大地震影響涮坐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸵膏,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一膊升、第九天 我趴在偏房一處隱蔽的房頂上張望怎炊。 院中可真熱鬧谭企,春花似錦、人聲如沸评肆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓜挽。三九已至盹廷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間久橙,已是汗流浹背俄占。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工管怠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缸榄。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓渤弛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甚带。 傳聞我的和親對象是個殘疾皇子她肯,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354