<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      你都用過SpringCloud的哪些組件,它們的原理是什么?

      前言

      看到文章的題目了嗎?就是這么抽象和籠統(tǒng)的一個問題,確實是我面試中真實被問到的,某共享貨車平臺的真實面試問題。
      SpringCloud確實是用過,但是那是三四年前了,那個時候SpringCloud剛開始流行沒多久,我們技術總監(jiān)讓我們調(diào)研一下,然后算上我在內(nèi)的三個同事就一人買了一本SpringCloud的書籍,開始看,開始研究,正好那個時候DDD也比較火,然后我們就一邊研究的SpringCloud一邊按照DDD的模型搭建自己的項目。
      但是這個項目最后做了三個月,才完成了一期。后面二期還沒開始,我就撤了。所以SpringCloud總共的使用時間就兩三個月,所以對這部分知識掌握的并不扎實,而且入職了新公司之后,都是使用公司自己封裝的框架,也已經(jīng)三年沒有用過SpringCloud了,這次是要面試換工作了,所以決定將這方面的知識,總結(jié)一下。

      服務治理 Spring Cloud Eureka

      我們之前在使用服務之間相互調(diào)用的時候,一般是靠一些靜態(tài)配置來完成的。比如服務A,要調(diào)用服務B來完成一個業(yè)務操作時,為了實現(xiàn)服務B的高可用,一般是通過手動配置來完成服務B的服務實例清單的維護。
      隨著業(yè)務的發(fā)展,系統(tǒng)功能越來越復雜,相應的服務不斷增加,而且服務的IP還一直在變化,靜態(tài)配置來維護各服務,就會變得越來越困難。
      在這里插入圖片描述
      這個時候就出現(xiàn)了服務治理框架,Spring Cloud Eureka。

      Spring Cloud Eureka 主要是圍繞著服務注冊與服務發(fā)現(xiàn)機制來完成對微服務的自動化管理的。

      服務注冊

      Eureka提供了服務端組件,我們也稱為注冊中心。每個服務都向Eureka的服務注冊中心,登記自己提供服務的元數(shù)據(jù),包括服務的ip地址、端口號、版本號、通信協(xié)議等。這樣注冊中心,就將各個服務維護在了一個服務清單中(雙層Map,第一層key是服務名,第二層key是實例名,value是服務地址加端口)。
      在這里插入圖片描述
      服務注冊中心,還會以心跳的方式去監(jiān)聽清單中的服務是否可用(默認30秒),若不可用(服務續(xù)約時間默認90秒),需從清單中剔除,達到排除故障服務的效果。
      Eureka注冊中心提供了高可用方案,可以支持集群部署注冊中心,然后多個注冊中心實例之間又相互注冊,這樣每個實例中都有一樣的服務清單了。

      但是Eureka為了提高注冊中心的高可用,所以對一致性的支持就沒有那么強了,這樣就導致了,當Eureka出現(xiàn)網(wǎng)絡問題時,每個節(jié)點為了保證高可用,會單獨提供服務這樣一致性就保證不了了,所以在CAP理論中,Eureka是保證了AP(可用性和分區(qū)容錯性)的。

      服務發(fā)現(xiàn)

      Eureka不但提供服務端,還提供了客戶端,客戶端是在各個服務中運行的。
      Eureka客戶端主要有兩個作用:

      • 向注冊中心注冊自身提供的服務,并周期性的發(fā)送心跳來更新它的服務租約
      • 同時,也能從服務端查詢當前注冊的服務信息,并把他們緩存到本地,并周期性的刷新服務狀態(tài)

      在Eureka Server中注冊的服務,相互之間調(diào)用,不再是通過指定的具體實例地址,而是通過向服務名發(fā)請求實現(xiàn)調(diào)用,因為每個服務服務都是多實例,并且實例地址還有可能經(jīng)常變。
      但是通過服務名稱調(diào)用,并不知道具體的服務實例位置,因此需要向注冊中心咨詢,并獲取所有服務實例清單,然后實現(xiàn)服務的請求訪問。

      舉例

      在這里插入圖片描述
      服務A的一個業(yè)務操作,需要調(diào)用服務B和服務C來完成。
      那么服務A和服務B和服務C都將自己注冊到Eureka的注冊中心,然后服務A通過咨詢注冊中心,將注冊中心的服務列表清單緩存到自己本地。
      通過服務名稱獲取到服務B和服務C的服務實例地址,最后通過一種輪詢策略取出一個具體的服務實例地址來進行調(diào)用。

      總結(jié)一下
      Eureka Client : 主要是將服務本身注冊到Eureka Server中,同時查詢Eureka Server的注冊服務列表緩存到本地
      Eureka Server:注冊中心,保存了所有注冊服務的元數(shù)據(jù),包括ip地址,端口等信息。

      客戶端負載均衡 Spring Cloud Ribbon

      服務的調(diào)用方,在通過Eureka Client緩存到本地的注冊表之后,通過服務名稱,找到具體的服務對應的實例地址,但是被調(diào)用方的服務地址是有多個的,那么該用那個地址去進行調(diào)用呢?

      服務A:
      192.168.12.10:9001
      192.168.12.11:9001
      192.168.12.12:9001
      

      這個時候Spring Cloud Ribbon就出現(xiàn)了,它是專門解決這個問題的,它的作用就是做負載均衡,會均勻的把請求分發(fā)到每臺機器上。

      Ribbon默認使用Round Ribbon的策略進行負載均衡,具體就是采用輪詢的方式進行請求。

      Ribbon除了有Round Ribbon這種輪詢策略,還有其他策略以及自定義策略。
      主要有:

      • RandomRole: 從服務實例清單中隨機選擇一個服務實例。
      • RoundRobinRule: 按照線性輪詢的方式依次選擇每個服務實例。
      • RetryRule:根據(jù)輪詢方式進行,且具備重試機制進行選擇實例。
      • WeightedResponseTimeRule:對RoundRobinRule的擴展,增加了根據(jù)實例的運行情況來計算權(quán)重,并根據(jù)權(quán)重來挑選實例。
      • ZoneAvoidanceRule:根據(jù)服務方的zone區(qū)域和可用性來輪詢選擇。

      Spring Cloud Ribbon具體的執(zhí)行示例如下:
      在這里插入圖片描述

      實例代碼

      下面的代碼就是通過Ribbon調(diào)用服務的代碼實例。

      @RestController
      public class ConsumerController {
          @Autowired
          RestTemplate restTemplate;
          @GetMapping("/ribbon-consumer")
          public String helloConsumer(){
              return restTemplate.getForEntity("http://example-service/index",String.class).getBody();
          }
      }
      

      可以看到Ribbon也是通過發(fā)起http請求,來進行的調(diào)用,只不過是通過調(diào)用服務名的地址來實現(xiàn)的。雖然說Ribbon不用去具體請求服務實例的ip地址或域名了,但是每調(diào)用一個接口都還要手動去發(fā)起Http請求,也是比較繁瑣的,而且返回類型也比較抽象,所以Spring Cloud對調(diào)用方式進行了升級封裝。

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

      Spring Cloud 為了簡化服務間的調(diào)用,在Ribbon的基礎上進行了進一步的封裝。單獨抽出了一個組件,就是Spring Cloud Feign。在引入Spring Cloud Feign后,我們只需要創(chuàng)建一個接口并用注解的方式來配置它,即可完成對服務提供方的接口綁定。

      Spring Cloud Feign具備可插拔的注解支持,并擴展了Spring MVC的注解支持。

      下面我們來看一個具體的例子:

      服務方具體的接口定義與實現(xiàn)代碼如下:

      
      import org.springframework.cloud.netflix.feign.FeignClient;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.bind.annotation.RequestParam;
      /**
       * 接口定義
       */
      @FeignClient(value="service-hi",fallback = TestFeignServiceImpl.class)
      public interface TestFeignService {
      
          @RequestMapping(value="/hi",method = RequestMethod.GET)
          String sayHi(@RequestParam("name") String name);
      }
      /**
       * 具體的服務實現(xiàn)
       */
      @Component
      public class TestFeignServiceImpl implements TestFeignService {
          @Override
          public String sayHi(String name) {
              return "你好,"+name;
          }
      }
      

      調(diào)用方的使用代碼如下:

      @RestController
      public class TestController
      {
          @Resource
          private TestFeignService testFeignService;
      
          @RequestMapping(value="/hi",method = RequestMethod.GET)
          public String sayHi(@RequestParam String name)
          {
          	// 調(diào)用遠程服務
              return testFeignService.sayHi(name);
          }
      }
      

      通過上面的代碼,我們可以看到,調(diào)用方通過Feign進程遠程服務調(diào)用的時候,非常簡單,就向是在調(diào)用本地服務一樣。

      像之前的建立連接,構(gòu)造請求,發(fā)起請求,獲取響應,解析響應等等操作,對使用者來說都是透明化的,使用者不用關心服務是怎么實現(xiàn)調(diào)用的,直接使用即可。

      那么Feign是如何實現(xiàn)這套封裝邏輯的呢?

      其實Feign底層主要是靠動態(tài)代理來實現(xiàn)這整個服務的調(diào)用過程的。
      主要邏輯如下:

      • 如果一個接口上定義了@FeignClient注解,F(xiàn)eign就會根據(jù)這個接口生成一個動態(tài)代理類。
      • 如果調(diào)用方,在調(diào)用這個定義了@FeignClient注解的接口時,本質(zhì)上是會調(diào)用Feign生成的代理類。
      • Feign生成的動態(tài)代理類,會根據(jù)具體接口方法中的@RequestMapping等注解,來動態(tài)構(gòu)造出需要請求的服務地址。
      • 最后針對這個地址,再通過Ribbon發(fā)起服務調(diào)用,解析響應等操作。

      在這里插入圖片描述
      因為Spring Cloud Feign的使用方式比Spring Cloud Ribbon更方便,所以一般項目中都是使用Feign,而且Feign還有繼承特性,可以將遠程服務接口繼承過來然后再進行自己的個性化擴展。因此Feign的使用范圍以及普及率更高一些。

      服務容錯保護 Spring Cloud Hystrix

      在微服務架構(gòu)中,我們將系統(tǒng)拆分成多個服務單元,各個服務之間通過服務注冊與訂閱的方式互相依賴。

      我們以一個電商網(wǎng)站下單的過程來舉例,在下單的業(yè)務操作過程中需要調(diào)用庫存服務,支付服務,積分、物流等服務。假設訂單服務最多同一時間只能處理50個請求,這個時候如果積分服務掛了,那么每次訂單服務去調(diào)用積分服務的時候,都會卡這么一段時間,然后才返回超時異常

      在這種場景下會有什么問題呢?

      如果目前電商網(wǎng)站正在搞活動,進行搶購活動,下單的人非常多,這種高并發(fā)的場景下,訂單服務的已經(jīng)同時在處理50個下單請求了,并且都卡在了請求積分服務的過程中。訂單服務已經(jīng)沒有能力去處理其他請求了。

      那么其他服務再來調(diào)用訂單服務時,發(fā)訂單服務無響應,這樣就導致訂單服務也不可用了。然后其他依賴訂單服務的服務,也最終會導致不可用。這就是微服務架構(gòu)中的服務雪崩。

      在這里插入圖片描述

      就上圖所示,如果多個服務之間相互調(diào)用,而不做任何保護措施的話,那么一個服務掛了,就會產(chǎn)生連鎖反應,導致其他服務也掛了。

      其實就算是積分服務掛了,也并不應該導致訂單服務也掛了,積分服務掛了,我們可以跳過積分服務,或者是放一個默認值,然后繼續(xù)往下走,等著積分服務恢復了,可以手動恢復一下數(shù)據(jù)。

      那么Spring Cloud Hystrix就是解決這個問題的組件,他主要是起到熔斷,隔離,降級的作用。

      Spring Cloud Hystrix其實是會為每一個服務開辟一個線程池,然后每個線程池中的線程用于對服務的調(diào)用請求。這樣就算是積分服務掛了,那也只是調(diào)用積分服務的線程池出現(xiàn)問題了,而其他服務的線程池還正常工作。這就是服務的隔離。

      這樣訂單服務在的調(diào)用積分服務的時候,如果發(fā)現(xiàn)有問題了,積分服務可以通過Hystrix返回一個默認值(默認是5秒內(nèi)20次調(diào)用失敗就熔斷)。這樣訂單服務就不用在這里卡住了,可以繼續(xù)往下調(diào)用其他服務進行業(yè)務操作了。這就是服務的熔斷。

      雖然說是積分服務掛了,并且也返回了默認值了,但是后續(xù)如果積分服務恢復了,想恢復數(shù)據(jù)怎么辦呢?這個時候積分服務可以將接收到的請求記錄下來,或者是打到日志中,能為后面恢復數(shù)據(jù)提供依據(jù)就行。這就是服務的降級

      整個過程大致如下圖所示:
      在這里插入圖片描述

      API網(wǎng)關服務Spring Cloud Zuul

      通過上面幾個組件的結(jié)合使用,已經(jīng)能夠完成一個基本的微服務架構(gòu)了。但是當一個系統(tǒng)中微服務的數(shù)量逐漸增多時,一些通用的邏輯,例如:權(quán)限校驗機制,請求過濾,請求路由,限流等等,這些每個服務對外提供能力的時候都要考慮到的邏輯,就會變得冗余。

      這個時候API網(wǎng)關的概念應運而生,它類似于面向?qū)ο笤O計模式中的Facade模式(門面模式/外觀模式),所有的外部客戶端訪問都需要經(jīng)過它來進行調(diào)度和過濾。主要實現(xiàn)請求路由、負載均衡、校驗過濾、服務限流等功能。

      Spring Cloud Zuul就是Spring Cloud提供的API網(wǎng)關組件,它通過與Eureka進行整合,將自身注冊為Eureka下的應用,從Eureka下獲取所有服務的實例,來進行服務的路由。

      Zuul還提供了一套過濾器機制,開發(fā)者可以自己指定哪些規(guī)則的請求需要執(zhí)行校驗邏輯,只有通過校驗邏輯的請求才會被路由到具體服務實例上,否則返回錯誤提示。
      在這里插入圖片描述

      Spring Cloud Zuul的依賴包spring-cloud-starter-zuul本身就包含了對spring-cloud-starter-hystrixspring-cloud-starter-ribbon模塊的依賴,所以Zuul天生就擁有線程隔離和斷路器的自我保護功能,以及對服務調(diào)用的客戶端負載功能。

      Zuul的路由實現(xiàn)是通過Path和serviceId還實現(xiàn)的,path是一個http請求去除ip和端口號后的方法路徑,例如:http://192.168.20.12:9001/api-zuul/123,那么path就是/api-zuul/123,Zuul在配置時支持模糊匹配,若123是動態(tài)參數(shù),可以將path配置成/pai-zuul/**,serviceId就是服務在Eureka中注冊的服務名稱。

      zuul.routes.api-zuul.path= /api-zuul/**
      zuul.routes.api-zuul.serviceId= service-jimoer
      

      有了統(tǒng)一的網(wǎng)關后,再做統(tǒng)一的鑒權(quán)、限流、認證授權(quán)、安全等方面的工作就會變的更加方便了。

      總結(jié)

      上面總結(jié)了Spring Cloud的幾個核心組件,其實Spring Cloud 除了這幾個組件還有一些其他的組件,例如:

      • 分布式配置中心Spring Cloud Config
      • 消息總線Spring Cloud Bus
      • 消息驅(qū)動Spring Cloud Stream
      • 分布式服務跟蹤Spring Cloud Sleuth

      主要是后面這些組件我們平時用的不多,而且對于微服務來說有些是有替代品的,所以我暫時就沒有總結(jié)。還有一點畢竟我這次總結(jié)是為了解決面試的問題,所以后面如果在實際的工作中用到了剩下的這些組件,我會繼續(xù)總結(jié)的。

      好了,總結(jié)一下這次的幾個組件的內(nèi)容吧。

      • Spring Cloud Eureka 各個微服務在啟動時將自己注冊到Eureka Server中,并且各個服務中的Eureka Client又能從注冊中心獲取各個服務的實例地址清單。
      • Spring Cloud Ribbon 各個服務相互調(diào)用的時候,通過Ribbon來進行客戶端的負載均衡,從多個實例中根據(jù)一定的策略選擇一臺進行請求。
      • Spring Cloud Feign 基于動態(tài)代理機制,根據(jù)注解和參數(shù)拼接URL,選擇具體的服務實例發(fā)起請求,簡化了服務間相互調(diào)用的開發(fā)工作。
      • Spring Cloud Hystrix 調(diào)用每個服務的時候都是通過線程池中的線程來發(fā)起的,不同的服務走不同的線程池,實現(xiàn)了服務的隔離,而且服務不可用時還提供了熔斷機制以及支持降低措施。
      • Spring Cloud Zuul 外部請求統(tǒng)一通過Zuul網(wǎng)關來進入,支持自定義路由規(guī)則,自定義過濾規(guī)則,可以實現(xiàn)同一的鑒權(quán)、限流、認證等功能。

      最后來一個整體的架構(gòu)圖,將各個組件串起來。

      在這里插入圖片描述

      posted @ 2021-01-18 08:24  紀莫  閱讀(2476)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 毛片网站在线观看| 日韩人妻无码精品久久| 泾川县| 亚洲精品麻豆一二三区| 国产成人无码免费视频麻豆| 国产午夜亚洲精品一区| 亚洲高清成人av在线| 国产深夜福利视频在线| 中文字幕日韩人妻一区| 国产女人水真多18毛片18精品| 久久丁香五月天综合网| 日韩加勒比一本无码精品| 综合偷自拍亚洲乱中文字幕| 国产日韩入口一区二区| 天天爽夜夜爽人人爽曰| 毛片免费观看视频| 亚洲国产精品人人做人人爱| 国产爽视频一区二区三区| 国产91特黄特色A级毛片| 国产精品午夜福利在线观看| 国产麻豆放荡av激情演绎| 1精品啪国产在线观看免费牛牛| 免费观看全黄做爰大片| 少妇被粗大的猛烈xx动态图| 亚洲最大中文字幕无码网站| 激情综合网激情综合网激情| 福利一区二区在线播放| 日韩人妻熟女中文字幕a美景之屋| 香港特级三A毛片免费观看| 免费看久久妇女高潮a| 鲁丝片一区二区三区免费| 蜜桃一区二区三区在线看| 国产精品免费观在线| 欧美视频精品免费覌看| 久久亚洲av成人一二三区| 国产在线精品福利91香蕉| 爱性久久久久久久久| 日韩丝袜欧美人妻制服| 黄网站色视频免费观看| 国产va免费精品观看精品| 中文字幕一区二区三区精彩视频|