<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>

          SpringCloudRPC遠(yuǎn)程調(diào)用核心原理:Feign遠(yuǎn)程調(diào)用的執(zhí)行流程

          共 5812字,需瀏覽 12分鐘

           ·

          2022-03-10 08:37

          Feign遠(yuǎn)程調(diào)用的執(zhí)行流程

          由于Feign中生成RPC接口JDK動態(tài)代理實(shí)例涉及的InvocationHandler調(diào)用處理器有多種,導(dǎo)致Feign遠(yuǎn)程調(diào)用的執(zhí)行流程稍微有所區(qū)別,但是遠(yuǎn)程調(diào)用執(zhí)行流程的主要步驟是一致的。這里主要介紹與兩類InvocationHandler調(diào)用處理器相關(guān)的RPC執(zhí)行流程:

          (1)與默認(rèn)的調(diào)用處理器FeignInvocationHandler相關(guān)的RPC執(zhí)行流程。

          (2)與Hystrix調(diào)用處理器HystrixInvocationHandler相關(guān)的RPC執(zhí)行流程。

          還是以uaa-provider啟動過程中的DemoClient接口的動態(tài)代理實(shí)例的執(zhí)行過程為例演示和分析遠(yuǎn)程調(diào)用的執(zhí)行流程。

          與FeignInvocationHandler相關(guān)的遠(yuǎn)程調(diào)用執(zhí)行流程

          FeignInvocationHandler是默認(rèn)的調(diào)用處理器,如果進(jìn)行特殊的配置,那么Feign將默認(rèn)使用此調(diào)用處理器。

          結(jié)合uaa-provider服務(wù)中DemoClient的動態(tài)代理實(shí)例的hello()方法遠(yuǎn)程調(diào)用執(zhí)行過程,這里詳細(xì)介紹與FeignInvocationHandler相關(guān)的遠(yuǎn)程調(diào)用執(zhí)行流程,如圖3-25所示。

          圖3-25 與FeignInvocationHandler相關(guān)的遠(yuǎn)程調(diào)用執(zhí)行流程

          整體的遠(yuǎn)程調(diào)用執(zhí)行流程大致分為4步,具體如下:

          (1)通過Spring IOC容器實(shí)例完成動態(tài)代理實(shí)例的裝配。

          前文講到,F(xiàn)eign在啟動時會為加上了@FeignClient注解的所有遠(yuǎn)程接口(包括DemoClient接口)創(chuàng)建一個FactoryBean工廠實(shí)例,并注冊到Spring IOC容器。然后在uaa-provider的DemoRPCController控制層類中,通過@Resource注解從Spring IOC容器找到FactoryBean工廠實(shí)例,通過其getObject()方法獲取到動態(tài)代理實(shí)例,裝配給DemoRPCController實(shí)例的成員變量demoClient。

          在需要進(jìn)行hello()遠(yuǎn)程調(diào)用時,直接通過demoClient成員變量調(diào)用JDK動態(tài)代理實(shí)例的hello()方法。

          (2)執(zhí)行InvocationHandler調(diào)用處理器的invoke(...)方法。

          前面講到,JDK動態(tài)代理實(shí)例的方法調(diào)用過程是通過委托給InvocationHandler調(diào)用處理器完成的,故在調(diào)用demoClient的hello()方法時,會調(diào)用到它的調(diào)用處理器FeignInvocationHandler實(shí)例的invoke(...)方法。

          大家知道,F(xiàn)eignInvocationHandler實(shí)例內(nèi)部保持了一個遠(yuǎn)程調(diào)用方法反射實(shí)例和方法處理器的dispatch映射。FeignInvocationHandle在它的invoke(...)方法中會根據(jù)hello()方法的Java反射實(shí)例在dispatch映射對象中找到對應(yīng)的MethodHandler方法處理器,然后由后者完成實(shí)際的HTTP請求和結(jié)果的處理。

          (3)執(zhí)行MethodHandler方法處理器的invoke(...)方法。

          通過前面關(guān)于MethodHandler方法處理器的組件介紹,大家都知道,feign默認(rèn)的方法處理器為SynchronousMethodHandler同步調(diào)用處理器,它的invoke(...)方法主要通過內(nèi)部feign。Client類型的client成員實(shí)例完成遠(yuǎn)程URL請求執(zhí)行和獲取遠(yuǎn)程結(jié)果。

          feign.Client客戶端有多種類型,不同的類型完成URL請求處理的具體方式不同。(4)通過feign.Client客戶端成員完成遠(yuǎn)程URL請求執(zhí)行和獲取遠(yuǎn)程結(jié)果。

          如果MethodHandler方法處理器client成員實(shí)例是默認(rèn)的feign.Client.Default實(shí)現(xiàn)類,就通過JDK自帶的HttpURLConnnection類完成遠(yuǎn)程URL請求執(zhí)行和獲取遠(yuǎn)程結(jié)果。

          如果MethodHandler方法處理器實(shí)例的client客戶端是ApacheHttpClient客戶端實(shí)現(xiàn)類,就使用ApacheHttpClient開源組件完成遠(yuǎn)程URL請求執(zhí)行和獲取遠(yuǎn)程結(jié)果。

          如果MethodHandler方法處理器實(shí)例的client客戶端是LoadBalancerFeignClient負(fù)載均衡客戶端實(shí)現(xiàn)類,就使用Ribbon結(jié)算出最佳的Provider節(jié)點(diǎn),然后由內(nèi)部的delegate委托客戶端成員去請求Provider服務(wù),完成URL請求處理。

          以上4步基本上就是Spring Cloud中的Feign遠(yuǎn)程調(diào)用的執(zhí)行流程。

          然而,默認(rèn)的基于FeignInvocationHandler調(diào)用處理器的執(zhí)行流程在運(yùn)行機(jī)制和調(diào)用性能上都滿足不了生產(chǎn)環(huán)境的要求,大致原因有以下兩點(diǎn):

          (1)在遠(yuǎn)程調(diào)用過程中沒有異常的熔斷監(jiān)測和恢復(fù)機(jī)制。

          (2)沒有用到高性能的HTTP連接池技術(shù)。

          接下來將為大家介紹一種結(jié)合Hystrix進(jìn)行RPC保護(hù)的遠(yuǎn)程調(diào)用處理流程。在該流程中所使用的InvocationHandler調(diào)用處理器叫作HystrixInvocationHandler調(diào)用處理器。

          這里作為鋪墊,首先為大家介紹HystrixInvocationHandler調(diào)用處理器本身的具體實(shí)現(xiàn)。

          ?與HystrixInvocationHandler相關(guān)的遠(yuǎn)程調(diào)用執(zhí)行流程

          HystrixInvocationHandler調(diào)用處理器類位于feign.hystrix包中,其字節(jié)碼文件不是處于feign核心包feign-core-*.jar中,而是在擴(kuò)展包feignhystrix-*.jar中。這里的*表示的是與Spring Cloud版本配套的版本號,當(dāng)Spring Cloud的版本為Finchley.RELEASE時,feign-core和feign-hystrix兩個JAR包的版本號都為9.5.1。

          HystrixInvocationHandler是具備RPC保護(hù)能力的調(diào)用處理器,它實(shí)現(xiàn)了InvocationHandler接口,對接口的invoke(...)抽象方法的實(shí)現(xiàn)如下:

          package feign.hystrix;
          //省略import
          final class HystrixInvocationHandler implements InvocationHandler {
          ...
          //... Map映射:Key為RPC方法的反射實(shí)例,value為方法處理器
          private final Map dispatch;
          ...
          public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
          //創(chuàng)建一個HystrixCommand命令,對同步方法調(diào)用器進(jìn)行封裝
          HystrixCommand hystrixCommand =
          new HystrixCommand
          ( (Setter)this.setterMethodMap.get(method) )
          {
          protected Object run() throws Exception {
          try {
          SynchronousMethodHandler handler=HystrixInvocationHandler.this.dispatch.get(method);
          return handler.invoke(args);
          } catch (Exception var2) {
          throw var2;
          } catch (Throwable var3) {
          throw (Error)var3;
          }
          }
          protected Object getFallback() {
          //省略HystrixCommand的異?;卣{(diào)
          }
          };
          //根據(jù)method的返回值類型,或返回hystrixCommand,或直接執(zhí)行
          if (this.isReturnsHystrixCommand(method)) {
          return hystrixCommand;
          } else if (this.isReturnsObservable(method)) {
          return hystrixCommand.toObservable();
          } else if (this.isReturnsSingle(method)) {
          return hystrixCommand.toObservable().toSingle();
          } else {
          //直接執(zhí)行
          return this.isReturnsCompletable(method) ?
          hystrixCommand.toObservable().toCompletable() : hystrixCommand.execute();
          }
          ...
          }

          HystrixInvocationHandler調(diào)用處理器與默認(rèn)調(diào)用處理器FeignInvocationHandler有一個共同點(diǎn):都有一個非常重要的Map類型成員dispatch映射,保存著RPC方法反射實(shí)例到MethodHandler方法處理器的映射。

          在源碼中,HystrixInvocationHandler的invoke(...)方法會創(chuàng)建hystrixCommand命令實(shí)例,對從dispatch獲取的SynchronousMethodHandler實(shí)例進(jìn)行封裝,然后對RPC方法實(shí)例method進(jìn)行判斷,判斷是直接返回hystrixCommand命令實(shí)例,還是立即執(zhí)行其execute()方法。默認(rèn)情況下,都是立即執(zhí)行它的execute()方法。

          HystrixCommand具備熔斷、隔離、回退等能力,如果它的run()方法執(zhí)行發(fā)生異常,就會執(zhí)行g(shù)etFallback()失敗回調(diào)方法,這一點(diǎn)后面會詳細(xì)介紹。

          回到uaa-provider服務(wù)中DemoClient動態(tài)代理實(shí)例的hello()方法的具體執(zhí)行過程,在執(zhí)行命令處理器hystrixCommand實(shí)例的run()方法時,步驟如下:

          (1)根據(jù)RPC方法DemoClient.hello()的反射實(shí)例在dispatch映射對象中找到對應(yīng)的方法處理器MethodHandler實(shí)例。

          (2)調(diào)用MethodHandler方法處理器的invoke(...)方法完成實(shí)際的hello()方法所配置的遠(yuǎn)程URL的HTTP請求和結(jié)果的處理。

          如果MethodHandler內(nèi)的RPC調(diào)用出現(xiàn)異常,比如遠(yuǎn)程server宕機(jī)、網(wǎng)絡(luò)延遲太大而導(dǎo)致請求超時、遠(yuǎn)程server來不及響應(yīng)等,hystrixCommand命令器就會調(diào)用失敗回調(diào)方法getFallback()返回回退結(jié)果。

          而hystrixCommand的getFallback()方法最終會調(diào)用配置在RPC接口@FeignClient注解的fallback屬性上的失敗回退類中對應(yīng)的回退方法,執(zhí)行業(yè)務(wù)級別的失敗回退處理。

          使用HystrixInvocationHandler方法處理器進(jìn)行遠(yuǎn)程調(diào)用,總體流程與使用默認(rèn)的方法處理器FeignInvocationHandler進(jìn)行遠(yuǎn)程調(diào)用大致是相同的。

          以uaa-provider模塊的DemoClient中hello()方法的遠(yuǎn)程調(diào)用執(zhí)行過程為例,進(jìn)行整體流程的展示,具體的時序圖如圖3-26所示。

          圖3-26 與HystrixInvocationHandler相關(guān)的遠(yuǎn)程調(diào)用執(zhí)行流程

          總體來說,使用HystrixInvocationHandler處理器的執(zhí)行流程與使用FeignInvocationHandler默認(rèn)的調(diào)用處理器相比大致是相同的。不同的是,HystrixInvocationHandler增加了RPC的保護(hù)機(jī)制。

          Feign遠(yuǎn)程調(diào)用的完整流程及其特性

          Feign是一個聲明式的RPC調(diào)用組件,它整合了Ribbon和Hystrix,使得服務(wù)調(diào)用更加簡單。Feign提供了HTTP請求的模板,通過編寫簡單的接口和方法注解就可以定義好HTTP請求的參數(shù)、格式、地址等信息。

          Feign極大地簡化了RPC遠(yuǎn)程調(diào)用,大家只需要像調(diào)用普通方法一樣就可以完成RPC遠(yuǎn)程調(diào)用。

          Feign遠(yuǎn)程調(diào)用的核心是通過一系列封裝和處理,將以JAVA注解方式定義的RPC方法最終轉(zhuǎn)換成HTTP請求,然后將HTTP請求的響應(yīng)結(jié)果解碼成POJO對象返回給調(diào)用者。

          Feign遠(yuǎn)程調(diào)用的完整流程如圖3-27所示。

          圖3-27 Feign遠(yuǎn)程調(diào)用的完整流程

          從圖3-27可以看到,F(xiàn)eign通過對RPC注解的解析將請求模板化。當(dāng)實(shí)際調(diào)用時傳入?yún)?shù),再根據(jù)參數(shù)應(yīng)用到請求模板上,進(jìn)而轉(zhuǎn)化成真正的Request請求。通過Feign及其動態(tài)代理機(jī)制,Java開發(fā)人員不用再通過HTTP框架封裝HTTP請求報文的方式完成遠(yuǎn)程服務(wù)的HTTP調(diào)用。

          Spring Cloud Feign具有如下特性:

          (1)可插拔的注解支持,包括Feign注解和Spring MVC注解。

          (2)支持可插拔的HTTP編碼器和解碼器。

          (3)支持Hystrix和它的RPC保護(hù)機(jī)制。

          (4)支持Ribbon的負(fù)載均衡。

          (5)支持HTTP請求和響應(yīng)的壓縮。

          總體來說,使用Spring Cloud Feign組件本身整合了Ribbon和Hystrix,可設(shè)計一套穩(wěn)定可靠的彈性客戶端調(diào)用方案,避免整個系統(tǒng)出現(xiàn)雪崩效應(yīng)。

          本文給大家講解的內(nèi)容是SpringCloudRPC遠(yuǎn)程調(diào)用核心原理:Feign遠(yuǎn)程調(diào)用的執(zhí)行流程

          1. 下篇文章給大家講解的是SpringCloudRPC遠(yuǎn)程調(diào)用核心原理:HystrixFeign動態(tài)代理實(shí)例的創(chuàng)建流程;

          2. 覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;

          3. 感謝大家的支持!


          本文就是愿天堂沒有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學(xué)習(xí)更多的話可以到微信公眾號里找我,我等你哦。

          瀏覽 44
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                    免费无码国产在线观看 | 欧美精品久久人妻无码免费视频 | 亚洲AV无码成人精品区在线播放 | 亚洲狼人久久久精品 | 区美XXXXX在线 |