SpringCloud(0) 外行人都能看懂的SpringCloud,錯過了血虧!

1、前言

只有光頭才能變強html

認識個人朋友可能都知道我這陣子去實習啦,去的公司說是用SpringCloud(但我以爲使用的力度並不大啊~~)...前端

因此,這篇主要來說講SpringCloud的一些基礎的知識。(我就是現學現賣了,主要當作我學習SpringCloud的筆記吧!)固然了,個人水平是有限的,可能會有一些理解錯的的概念/知識點,還請你們不吝在評論區指正啊~~java

SpringCloud GitHub Demo(看完文章的同窗能夠本身練手玩玩):nginx

項目結構圖:git

 

 

2、集羣/分佈式/微服務/SOA是什麼?

像我這種技術小白,看到這些詞(集羣/分佈式/微服務/SOA)的時候,感受就是高不可攀的(高大尚的技術!!)。就好像剛學Java面向對象的時候,在論壇上翻閱資料的時候,無心看到"面向切面編程",也認爲這是高不可攀的(高大尚的技術!!)。程序員

但真正接觸到"面向切面編程"的時候,發現原來就是如此啊,也沒什麼大不了的。只不過當時被它的名字給唬住了...github

不知道各位在剛接觸這些名字集羣/分佈式/微服務/SOA的時候,有沒有被唬住了呢??web

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

2.1什麼是集羣

如下內容來源維基百科:算法

計算機集羣簡稱集羣是一種計算機系統,它經過一組鬆散集成的計算機軟件和/或硬件鏈接起來高度緊密地協做完成計算工做。在某種意義上,他們能夠被看做是一臺計算機。集羣系統中的單個計算機一般稱爲節點,一般經過局域網鏈接,但也有其它的可能鏈接方式。集羣計算機一般用來改進單個計算機的計算速度和/或可靠性。通常狀況下集羣計算機比單個計算機,好比工做站或超級計算機性能價格比要高得多spring

集羣技術特色:

  • 經過多臺計算機完成同一個工做,達到更高的效率。
  • 兩機或多機內容、工做過程等徹底同樣。若是一臺死機,另外一臺能夠起做用。

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

  • 小周在公司寫Java程序,但公司業務在發展,一個Java開發者可能忙不過來,小周有的時候也得請個假呀。因而請了3y過去一塊兒作Java開發。平時小周和3y就寫Java程序,但3y可能有事要回學校一趟。沒事,公司還有小周作Java開發呢,公司開發還能繼續運做。
    • 3y跟小周都是作Java開發。
    • 3y來了,小周的工做能夠分擔一些。
    • 3y請假了,還有小周在呢。

我寫了一個910便利網發佈到服務器去了,如今愈來愈多的人訪問了,訪問有點慢,怎麼辦???很簡單,(只有充錢才能變強),加配置吧(加cpu,加內存)。升級完配置以後,訪問人數愈來愈多,因而發現又不由用啦,在這臺機器上加配置已經解決不了了,怎麼辦???很簡單,(只有充錢才能變強),我再買一臺服務器,將910便利網也發佈到新買的這臺服務器上去。

特色:

  • 這兩臺服務器都是運行同一個系統--->910便利網

好處:

  • 原本只有一臺機器處理訪問,如今有兩臺機器處理訪問了,分擔了壓力。
  • 若是其中一臺忘記繳費了,暫時用不了了。不要緊,還有另外一臺能夠用呢。

集羣:同一個業務,部署在多個服務器上(不一樣的服務器運行一樣的代碼,幹同一件事)

2.2什麼是分佈式

如下內容來源維基百科:

分佈式系統是一組計算機,經過網絡相互鏈接傳遞消息與通訊後並協調它們的行爲而造成的系統。組件之間彼此進行交互以實現一個共同的目標。

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

  • 如今公司有小周和3y一塊兒作Java開發,作Java開發通常jQuery,AJAX都能寫一點,因此這些活都由咱們來幹。但是呢,3y對前端不是很熟,有的時候調試半天都調不出來。老闆認爲3y是真的菜!因而讓小周專門來處理前端的事情。這樣3y就高興了,能夠專心寫本身的Java,前端就專門交由小周負責了。因而,小周和3y就變成了協做開發。
    • 3y對前端不熟(能寫出來),但在調試的時候可能會花費不少時間
    • 小周來專門作前端的事,3y能夠專心寫本身的Java程序了。
    • 都是爲了項目正常運行以及迭代。

個人910便利網已經部署到兩臺服務器去了,可是愈來愈多的人去訪問。如今也逐漸承受不住啦。那如今怎麼辦啊??那繼續充錢變強??做爲一個理智的我,確定得想一想是哪裏有問題。如今910便利網的模塊有好幾個,全都丟在同一個Tomcat裏邊。

其實有些模塊的訪問是很低的(好比後臺管理),那我可不能夠這樣作:將每一個模塊抽取獨立出來,訪問量大的模塊用好的服務器裝着,沒啥人訪問的模塊用差的服務器裝着。這樣的好處是:1、資源合理利用了(沒人訪問的模塊用性能差的服務器,訪問量大的模塊單獨提高性能就行了)。2、耦合度下降了:每一個模塊獨立出來,各幹各的事(專業的人作專業的事),便於擴展

特色:

  • 將910便利網的功能拆分,模塊之間獨立,在使用的時候再將這些獨立的模塊組合起來就是一個系統了。

好處:

  • 模塊之間獨立,各作各的事,便於擴展,複用性高
  • 高吞吐量。某個任務須要一個機器運行10個小時,將該任務用10臺機器的分佈式跑(將這個任務拆分紅10個小任務),可能2個小時就跑完了

分佈式:一個業務分拆多個子業務,部署在不一樣的服務器上(不一樣的服務器,運行不一樣的代碼,爲了同一個目的)

2.3集羣/分佈式

集羣和分佈式並不衝突,能夠有分佈式集羣

如今3y的公司規模變大了,有5個小夥子寫Java,4個小夥子寫前端,2個小夥子作測試,1個小夥子作DBA。

  • Java,前端,測試,DBA的關係看做是分佈式的
  • 5個Java看做是集羣的(前端,測試同理)...

2.4分佈式/微服務/SOA

其實我認爲分佈式/微服務/SOA這三個概念是差很少的,瞭解了其中的一個,而後將本身的理解往上面套就行了。不必細分每一個的具體概念~~(固然了,我很期待有大佬能夠在評論區留言說下本身的見解哈)

參考資料:

3、CAP理論

從上面所講的分佈式概念咱們已經知道,分佈式簡單理解就是:一個業務分拆多個子業務,部署在不一樣的服務器上

  • 通常來講,一個子業務咱們稱爲節點。

若是你接觸過一些分佈式的基礎概念,那確定會聽過CAP這個理論。就好比說:你學了MySQL的InnoDB存儲引擎相關知識,你確定聽過ACID!

首先,咱們來看一下CAP分別表明的是什麼意思:

  • C:數據一致性(consistency)
    • 全部節點擁有數據的最新版本
  • A:可用性(availability)
    • 數據具有高可用性
  • P:分區容錯性(partition-tolerance)
    • 容忍網絡出現分區,分區之間網絡不可達。

下面有三個節點(它們是集羣的),此時三個節點都可以相互通訊:

 

 

因爲咱們的系統是分佈式的,節點之間的通訊是經過網絡來進行的。只要是分佈式系統,那頗有可能會出現一種狀況:由於一些故障,使得有些節點之間不連通了,整個網絡就分紅了幾塊區域。

  • 數據就散佈在了這些不連通的區域中,這就叫分區

 

 

如今出現了網絡分區後,此時有一個請求過來了,想要註冊一個帳戶。

 

 

此時咱們節點一和節點三是不可通訊的,這就有了抉擇:

  • 若是容許當前用戶註冊一個帳戶,此時註冊的記錄數據只會在節點一和節點二或者節點二和節點三同步,由於節點一和節點三的記錄不能同步的。
    • 這種狀況其實就是選擇了可用性(availability),拋棄了數據一致性(consistency)
  • 若是不容許當前用戶註冊一個帳戶(就是要等到節點一和節點三恢復通訊)。節點一和節點三一旦恢復通訊,咱們就能夠保證節點擁有的數據是最新版本。
    • 這種狀況其實就是拋棄了可用性(availability),選擇了數據一致性(consistency)

3.1再次梳理一下CAP理論

通常咱們說的分佈式系統,P:分區容錯性(partition-tolerance)這個是必需的,這是客觀存在的。

CAP是沒法徹底兼顧的,從上面的例子也能夠看出,咱們能夠選AP,也能夠選CP。可是,要注意的是:不是說選了AP,C就徹底拋棄了。不是說選了CP,A就徹底拋棄了!

在CAP理論中,C所表示的一致性是強一致性(每一個節點的數據都是最新版本),其實一致性還有其餘級別的:

  • 弱一致性:弱一致性是相對於強一致性而言,它不保證總能獲得最新的值;
  • 最終一致性(eventual consistency):放寬對時間的要求,在被調完成操做響應後的某個時間點,被調多個節點的數據最終達成一致

可用性的值域能夠定義成0到100%的連續區間。

 

 

因此,CAP理論定義的實際上是在容忍網絡分區的條件下,「強一致性」和「極致可用性」沒法同時達到。

參考資料:

擴展閱讀:

4、SpringCloud就是這麼簡單

相信你們讀到這裏,對分佈式/微服務已經有必定的瞭解了,其實單從概念來講,是很是容易理解的。只是極可能被它的名字給唬住了。

下面我就來說講SpringCloud最基礎的知識~

4.1爲何須要SpringCloud?

前面也講了,從分佈式/微服務的角度而言:就是把咱們一大的項目,分解成多個小的模塊。這些小的模塊組合起來,完成功能。

舉個可能不太恰當的例子(現實可能不會這麼拆分,但意思到位就行了):

 

 

拆分出多個模塊之後,就會出現各類各樣的問題,而SpringCloud提供了一整套的解決方案!

  • 注:這些模塊是獨立成一個子系統的(不一樣主機)。

SpringCloud的基礎功能:

  • 服務治理: Spring Cloud Eureka
  • 客戶端負載均衡: Spring Cloud Ribbon
  • 服務容錯保護: Spring Cloud Hystrix
  • 聲明式服務調用: Spring Cloud Feign
  • API網關服務:Spring Cloud Zuul
  • 分佈式配置中心: Spring Cloud Config

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

  • 消息總線: Spring Cloud Bus
  • 消息驅動的微服務: Spring Cloud Stream
  • 分佈式服務跟蹤: Spring Cloud Sleuth

5、引出Eureka

那會出現什麼問題呢??首當其衝的就是子系統之間的通信問題。子系統與子系統之間不是在同一個環境下,那就須要遠程調用。遠程調用可能就會想到httpClient,WebService等等這些技術來實現。

既然是遠程調用,就必須知道ip地址,咱們可能有如下的場景。

  • 功能實現一:A服務須要調用B服務
    • 在A服務的代碼裏面調用B服務,顯式經過IP地址調用:http://123.123.123.123:8888/java3y/3
  • 功能實現二:A服務調用B服務,B服務調用C服務,C服務調用D服務
    • 在A服務的代碼裏面調用B服務,顯式經過IP地址調用:http://123.123.123.123:8888/java3y/3,(一樣地)B->C,C->D
  • 功能實現三:D服務調用B服務,B服務調用C服務
    • 在D服務的代碼裏面調用B服務,顯式經過IP地址調用:http://123.123.123.123:8888/java3y/3,(一樣地)B->C
  • .....等等等等

萬一,咱們B服務的IP地址變了,想一想會出現什麼問題:A服務,D服務(等等)須要手動更新B服務的地址

  • 在服務多的狀況下,手動來維護這些靜態配置就是噩夢!

爲了解決微服務架構中的服務實例維護問題(ip地址), 產生了大量的服務治理框架和產品。 這些框架和產品的實現都圍繞着服務註冊與服務發現機制來完成對微服務應用實例的自動化管理。

在SpringCloud中咱們的服務治理框架通常使用的就是Eureka。

咱們的問題:

  • 如今有A、B、C、D四個服務,它們之間會互相調用(並且IP地址極可能會發生變化),一旦某個服務的IP地址變了,那服務中的代碼要跟着變,手動維護這些靜態配置(IP)很是麻煩!

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

  • 建立一個E服務,將A、B、C、D四個服務的信息都註冊到E服務上,E服務維護這些已經註冊進來的信息

 

 

A、B、C、D四個服務均可以拿到Eureka(服務E)那份註冊清單。A、B、C、D四個服務互相調用再也不經過具體的IP地址,而是經過服務名來調用!

  • 拿到註冊清單--->註冊清單上有服務名--->天然就可以拿到服務具體的位置了(IP)。
  • 其實簡單來講就是:代碼中經過服務名找到對應的IP地址(IP地址會變,但服務名通常不會變)

 

 

5.1Eureka細節

Eureka專門用於給其餘服務註冊的稱爲Eureka Server(服務註冊中心),其他註冊到Eureka Server的服務稱爲Eureka Client。

 

 

在Eureka Server通常咱們會這樣配置:

 register-with-eureka: false #false表示不向註冊中心註冊本身。  fetch-registry: false #false表示本身端就是註冊中心,個人職責就是維護服務實例,並不須要去檢索服務 複製代碼

Eureka Client分爲服務提供者和服務消費者。

  • 但極可能,某服務既是服務提供者又是服務消費者。

若是在網上看到SpringCloud的某個服務配置沒有"註冊"到Eureka-Server也不用過於驚訝(可是它是能夠獲取Eureka服務清單的)

  • 極可能只是做者把該服務認做爲單純的服務消費者,單純的服務消費者無需對外提供服務,也就無須註冊到Eureka中了
eureka:  client:  register-with-eureka: false # 當前微服務不註冊到eureka中(消費端)  service-url:  defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 複製代碼

下面是Eureka的治理機制:

  • 服務提供者
    • 服務註冊:啓動的時候會經過發送REST請求的方式將本身註冊到Eureka Server上,同時帶上了自身服務的一些元數據信息。
    • **服務續約:**在註冊完服務以後,服務提供者會維護一個心跳用來持續告訴Eureka Server: "我還活着 」 、
    • 服務下線:當服務實例進行正常的關閉操做時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務註冊中心:「我要下線了 」。
  • 服務消費者
    • 獲取服務:當咱們啓動服務消費者的時候,它會發送一個REST請求給服務註冊中心,來獲取上面註冊的服務清單
    • 服務調用:服務消費者在獲取服務清單後,經過服務名能夠得到具體提供服務的實例名和該實例的元數據信息。在進行服務調用的時候,優先訪問同處一個Zone中的服務提供方。
  • Eureka Server(服務註冊中心):
    • **失效剔除:**默認每隔一段時間(默認爲60秒) 將當前清單中超時(默認爲90秒)沒有續約的服務剔除出去。
    • 自我保護:。EurekaServer 在運行期間,會統計心跳失敗的比例在15分鐘以內是否低於85%(一般因爲網絡不穩定致使)。 Eureka Server會將當前的實例註冊信息保護起來, 讓這些實例不會過時,儘量保護這些註冊信息。

最後,咱們就有了這張圖:

 

 

舉個例子:

  • 3y跟女友去東站的東方寶泰逛街,但不知道東方寶泰有什麼好玩的。因而就去物業搜了一下東方寶泰商戶清單,發現一樓有優衣庫,二樓有星巴克,三樓有麥當勞。
  • 在優衣庫旁邊,有新開張的KFC,在牆壁打上了很大的標識「歡迎KFC入駐東方寶泰」。
  • 商家們須要定時交物業費給物業。
  • 物業維持東方寶泰的穩定性。若是某個商家不想在東方寶泰運營了,告訴了物業。物業天然就會將其在東方寶泰商戶清單去除。

優秀博文:

6、引出RestTemplate和Ribbon

經過Eureka服務治理框架,咱們能夠經過服務名來獲取具體的服務實例的位置了(IP)。通常在使用SpringCloud的時候不須要本身手動建立HttpClient來進行遠程調用。

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

// 傳統的方式,直接顯示寫死IP是很差的! //private static final String REST_URL_PREFIX = "http://localhost:8001"; // 服務實例名 private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT"; /** * 使用 使用restTemplate訪問restful接口很是的簡單粗暴無腦。 (url, requestMap, * ResponseBean.class)這三個參數分別表明 REST請求地址、請求參數、HTTP響應轉換被轉換成的對象類型。 */ @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); } 複製代碼

爲了實現服務的高可用,咱們能夠將服務提供者集羣。好比說,如今一個秒殺系統設計出來了,準備上線了。在11月11號時爲了可以支持高併發,咱們開多臺機器來支持併發量。

 

 

如今想要這三個秒殺系統合理攤分用戶的請求(專業來講就是負載均衡),可能你會想到nginx。

其實SpringCloud也支持的負載均衡功能,只不過它是客戶端的負載均衡,這個功能實現就是Ribbon!

負載均衡又區分了兩種類型:

  • 客戶端負載均衡(Ribbon)
    • 服務實例的清單在客戶端,客戶端進行負載均衡算法分配。
    • (從上面的知識咱們已經知道了:客戶端能夠從Eureka Server中獲得一份服務清單,在發送請求時經過負載均衡算法,在多個服務器之間選擇一個進行訪問)
  • 服務端負載均衡(Nginx)
    • 服務實例的清單在服務端,服務器進行負載均衡算法分配

因此,咱們的圖能夠畫成這樣:

 

 

6.1Ribbon細節

Ribbon是支持負載均衡,默認的負載均衡策略是輪詢,咱們也是能夠根據本身實際的需求自定義負載均衡策略的。

@Configuration public class MySelfRule { @Bean public IRule myRule() { //return new RandomRule();// Ribbon默認是輪詢,我自定義爲隨機 //return new RoundRobinRule();// Ribbon默認是輪詢,我自定義爲隨機 return new RandomRule_ZY();// 我自定義爲每臺機器5次 } } 複製代碼

實現起來也很簡單:繼承AbstractLoadBalancerRule類,重寫public Server choose(ILoadBalancer lb, Object key)便可。

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

舉個例子:

  • 3y跟女友過了幾個月,又去東方寶泰了。因爲記性很差,又去物業那弄了一份東方寶泰商戶清單。
  • 此次看到東方寶泰又開了一間麥當勞,一間在二樓,一間在三樓。原來生意太好了,爲了能提升用戶體驗,在二樓多開了一間麥當勞。
  • 這時,3y問女友:「去哪間麥當勞比較好?要不咱們拋硬幣決定?」3y女友說:」你是否是傻,確定哪間近去哪間啊「

優秀博文:

7、引出Hystrix

到目前爲止,咱們的服務看起來好像挺好的了:可以根據服務名來遠程調用其餘的服務,能夠實現客戶端的負載均衡。

 

 

可是,若是咱們在調用多個遠程服務時,某個服務出現延遲,會怎麼樣??

 

 

在高併發的狀況下,因爲單個服務的延遲,可能致使全部的請求都處於延遲狀態,甚至在幾秒鐘就使服務處於負載飽和的狀態,資源耗盡,直到不可用,最終致使這個分佈式系統都不可用,這就是「雪崩」。

 

 

針對上述問題, Spring Cloud Hystrix實現了斷路器、線程隔離等一系列服務保護功能。

  • Fallback(失敗快速返回):當某個服務單元發生故障(相似用電器發生短路)以後,經過斷路器的故障監控(相似熔斷保險絲), 向調用方返回一個錯誤響應, 而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間佔用不釋放,避免了故障在分佈式系統中的蔓延。
  • 資源/依賴隔離(線程池隔離):它會爲每個依賴服務建立一個獨立的線程池,這樣就算某個依賴服務出現延遲太高的狀況,也只是對該依賴服務的調用產生影響, 而不會拖慢其餘的依賴服務。

Hystrix提供幾個熔斷關鍵參數:滑動窗口大小(20)、 熔斷器開關間隔(5s)、錯誤率(50%)

  • 每當20個請求中,有50%失敗時,熔斷器就會打開,此時再調用此服務,將會直接返回失敗,再也不調遠程服務。
  • 直到5s鍾以後,從新檢測該觸發條件,判斷是否把熔斷器關閉,或者繼續打開。

Hystrix還有請求合併、請求緩存這樣強大的功能,在此我就不具體說明了,有興趣的同窗可繼續深刻學習~

7.1Hystrix儀表盤

Hystrix儀表盤:它主要用來實時監控Hystrix的各項指標信息。經過Hystrix Dashboard反饋的實時信息,能夠幫助咱們快速發現系統中存在的問題,從而及時地採起應對措施。

啓動時的頁面:

 

 

監控單服務的頁面:

 

 

咱們如今的服務是這樣的:

 

 

除了能夠開啓單個實例的監控頁面以外,還有一個監控端點 /turbine.stream是對集羣使用的。 從端點的命名中,能夠引入Turbine, 經過它來聚集監控信息,並將聚合後的信息提供給 HystrixDashboard 來集中展現和監控。

 

 

舉個例子:

  • 3y和女友決定去萬達玩,去到萬達的停車場發如今負一層已經大大寫上「負一層已停滿,請下負二層,負二層空餘停車位還有100個!」
  • 這時,3y就跟女友說:「萬達停車場是作得挺好的,若是它沒有直接告知我負一層已滿,可能我就去負一層找位置了,要是一堆人跑去負一層但都找不到車位的話,恐怕就塞死了」。3y接着說:「看停車位的狀態也作得不錯,在停車位上頭有一個感應(監控),若是是紅色就表明已被停了,若是是綠色就說明停車位是空的」。
  • 3y女友不屑的說:「你話是真的多」

參考資料:

8、引出Feign

上面已經介紹了Ribbon和Hystrix了,能夠發現的是:他倆做爲基礎工具類框架普遍地應用在各個微服務的實現中。咱們會發現對這兩個框架的使用幾乎是同時出現的。

爲了簡化咱們的開發,Spring Cloud Feign出現了!它基於 Netflix Feign 實現,整合了 Spring Cloud Ribbon 與 Spring Cloud Hystrix, 除了整合這二者的強大功能以外,它還提 供了聲明式的服務調用(再也不經過RestTemplate)。

Feign是一種聲明式、模板化的HTTP客戶端。在Spring Cloud中使用Feign, 咱們能夠作到使用HTTP請求遠程服務時能與調用本地方法同樣的編碼體驗,開發者徹底感知不到這是遠程方法,更感知不到這是個HTTP請求。

下面就簡單看看Feign是怎麼優雅地實現遠程調用的:

服務綁定:

// value --->指定調用哪一個服務 // fallbackFactory--->熔斷器的降級提示 @FeignClient(value = "MICROSERVICECLOUD-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class) public interface DeptClientService { // 採用Feign咱們可使用SpringMVC的註解來對服務進行綁定! @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中使用斷路器 * 這裏主要是處理異常出錯的狀況(降級/熔斷時服務不可用,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 + "沒有沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務Provider已經關閉") .setDb_source("no this database in MySQL"); } @Override public List<Dept> list() { return null; } @Override public boolean add(Dept dept) { return false; } }; } } 複製代碼

調用:

 

 

9、引出Zuul

基於上面的學習,咱們如今的架構極可能會設計成這樣:

 

 

這樣的架構會有兩個比較麻煩的問題:

  1. 路由規則與服務實例的維護間題:外層的負載均衡(nginx)須要維護全部的服務實例清單(圖上的OpenService)
  2. 簽名校驗、 登陸校驗冗餘問題:爲了保證對外服務的安全性, 咱們在服務端實現的微服務接口,每每都會有必定的權限校驗機制,但咱們的服務是獨立的,咱們不得不在這些應用中都實現這樣一套校驗邏輯,這就會形成校驗邏輯的冗餘。

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

 

 

每一個服務都有本身的IP地址,Nginx想要正確請求轉發到服務上,就必須維護着每一個服務實例的地址!

  • 更是災難的是:這些服務實例的IP地址還有可能會變,服務之間的劃分也極可能會變。
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

複製代碼

購物車和訂單模塊都須要用戶登陸了才能夠正常訪問,基於如今的架構,只能在購物車和訂單模塊都編寫校驗邏輯,這無疑是冗餘的代碼。

爲了解決上面這些常見的架構問題,API網關的概念應運而生。在SpringCloud中了提供了基於Netfl ix Zuul實現的API網關組件Spring Cloud Zuul。

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

  • SpringCloud Zuul經過與SpringCloud Eureka進行整合,將自身註冊爲Eureka服務治理下的應用,同時從Eureka中得到了全部其餘微服務的實例信息。外層調用都必須經過API網關,使得將維護服務實例的工做交給了服務治理框架自動完成。
  • 在API網關服務上進行統一調用來對微服務接口作前置過濾,以實現對微服務接口的攔截和校驗。

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

關於Zuul還有不少知識點(因爲篇幅問題,這裏我就不細說了):

  • 路由匹配(動態路由)
  • 過濾器實現(動態過濾器)
  • 默認會過濾掉Cookie與敏感的HTTP頭信息(額外配置)

9.1可能對Zuul的疑問

Zuul支持Ribbon和Hystrix,也可以實現客戶端的負載均衡。咱們的Feign不也是實現客戶端的負載均衡和Hystrix的嗎?既然Zuul已經可以實現了,那咱們的Feign還有必要嗎?

 

 

或者能夠這樣理解:

  • zuul是對外暴露的惟一接口至關於路由的是controller的請求,而Ribbonhe和Fegin路由了service的請求
  • zuul作最外層請求的負載均衡 ,而Ribbon和Fegin作的是系統內部各個微服務的service的調用的負載均衡

有了Zuul,還須要Nginx嗎?他倆能夠一塊兒使用嗎?

  • 個人理解:Zuul和Nginx是能夠一塊兒使用的(畢竟咱們的Zuul也是能夠搭成集羣來實現高可用的),要不要一塊兒使用得看架構的複雜度了(業務)~~~

參考資料:

10、引出SpringCloud Config

隨着業務的擴展,咱們的服務會愈來愈多,愈來愈多。每一個服務都有本身的配置文件。

既然是配置文件,給咱們配置的東西,那不免會有些改動的。

好比咱們的Demo中,每一個服務都寫上相同的配置文件。萬一咱們有一天,配置文件中的密碼須要更換了,那就得三個都要從新更改。

 

 

在分佈式系統中,某一個基礎服務信息變動,都極可能會引發一系列的更新和重啓

Spring Cloud Config項目是一個解決分佈式系統的配置管理方案。它包含了Client和Server兩個部分,server提供配置文件的存儲、以接口的形式將配置文件的內容提供出去,client經過接口獲取數據、並依據此數據初始化本身的應用。

  • 簡單來講,使用Spring Cloud Config就是將配置文件放到統一的位置管理(好比GitHub),客戶端經過接口去獲取這些配置文件。
  • 在GitHub上修改了某個配置文件,應用加載的就是修改後的配置文件。

 

 

SpringCloud Config其餘的知識:

  • 在SpringCloud Config的服務端, 對於配置倉庫的默認實現採用了Git,咱們也能夠配置SVN。
  • 配置文件內的信息加密和解密
  • 修改了配置文件,但願不用重啓來動態刷新配置,配合Spring Cloud Bus 使用~

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

總結

本文主要寫了SpringCloud的基礎知識,但願你們看完能有所幫助~

SpringCloud的資料也不少,我整理一些我認爲比較好,想要深刻的同窗不妨看看下邊的資源~~~

SpringCloud系列文章參考資料:

參考書籍:

  • 《SpringCloud 微服務實戰》

SpringCloud GitHub Demo(看完文章的同窗能夠本身練手玩玩,寫好了ReadMe了):

若是想看更多的原創技術文章,歡迎你們關注個人微信公衆號:Java3y。公衆號還有海量的視頻資源哦,關注便可免費領取。

 

可能感興趣的連接:

來源於:http://www.javashuo.com/article/p-pzkcxztb-cn.html

相關文章
相關標籤/搜索