亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解openfeign集成spring?cloud?loadbalancer實(shí)現(xiàn)負(fù)載均衡流程

 更新時(shí)間:2023年07月06日 09:45:07   作者:子瞻  
這篇文章主要介紹了openfeign集成spring?cloud?loadbalancer實(shí)現(xiàn)負(fù)載均衡流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Feignclient負(fù)載均衡中如何起作用

當(dāng)我們?cè)陧?xiàng)目中調(diào)用自己實(shí)現(xiàn)的Feignclient負(fù)載均衡中如何起作用?請(qǐng)看下圖:

圖一

在圖一中我們可以發(fā)現(xiàn),在ConsumerController中調(diào)用自定義的DemoFeignClient方法時(shí),通過spring容器中對(duì)DemoFeignclient的代理類的調(diào)用最終通過feign.SynchronousMethodHandler.invoke()->openfeign.loadbalancer.execute()->org.springframework.cloud.loadbalancer.blocking.client.FeignBlockingLoadBalancerClient.choose()->org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer.choose()這樣的調(diào)用鏈,最終執(zhí)行spring cloud loadbalaner中的輪詢負(fù)載均橫策略!

然而,上圖中的這些關(guān)鍵類是如何組合起來發(fā)揮作用呢?請(qǐng)我們一起繼續(xù)分析!spring cloud項(xiàng)目啟動(dòng)后,spring容器解析并加載LoadBalancerClientConfiguration.java配置文件(如下圖所示)

圖二

然后將"reactorServiceInstanceLoadBalancer"注冊(cè)到beanDefinitionMap中。
然后會(huì)掃描我們聲明的controller,因?yàn)閏onroller中注入了DemoFeignClient,因此spring容器會(huì)遞歸創(chuàng)建DemoFeignClient,創(chuàng)建DemoFiegnClient過程中會(huì)通過AbstractAutowireCapableBeanFactory.obtainFromSupplier()注入instanceSupplier實(shí)例,也就是FeignClientFactoryBean實(shí)例!

主要邏輯

下面是org.springframework.cloud.openfeign.FeignClientsRegistrar.registerFeignClient()方法主要邏輯:

private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,
            Map<String, Object> attributes) {
          //忽略非核心代碼片段
            BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> {
            //設(shè)置url
            factoryBean.setUrl(getUrl(beanFactory, attributes));
            //設(shè)置路徑
            factoryBean.setPath(getPath(beanFactory, attributes));
            //decode404 布爾值            factoryBean.setDecode404(Boolean.parseBoolean(String.valueOf(attributes.get("decode404"))));
            Object fallback = attributes.get("fallback");
            //設(shè)置fallback
            if (fallback != null) {
                factoryBean.setFallback(fallback instanceof Class ? (Class<?>) fallback
                        : ClassUtils.resolveClassName(fallback.toString(), null));
            }
            //設(shè)置fallback工廠類
            Object fallbackFactory = attributes.get("fallbackFactory");
            if (fallbackFactory != null) {
                factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class<?>) fallbackFactory
                        : ClassUtils.resolveClassName(fallbackFactory.toString(), null));
            }
            //實(shí)例化我們聲明的DemoClient
            return factoryBean.getObject();
        });
}

這還沒有完,org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject()中最終執(zhí)行l(wèi)oadBalance();在loadBalance()中實(shí)例化FeignInvocationHandler;

調(diào)用DemoFeignClient中方法

在項(xiàng)目啟動(dòng)成功之后,我們調(diào)用DemoFeignClient中的方法時(shí)

圖三

通過圖三可以發(fā)現(xiàn),描述DemoFeignClient的RootBeanDefinition的類中還有一個(gè)叫“instanceSupplier”的類型屬性,它的值是“FeignClientsRegistrar$lambda”,那么這個(gè)類時(shí)什么時(shí)候被注入進(jìn)來的呢?答案就是上面分析項(xiàng)目啟動(dòng)過程中spring容器根據(jù)RootBeanDefinition對(duì)DemoFeignClient的描述,通過對(duì)"FeignClientsRegistrar$lambda"的調(diào)用完成對(duì)DemoFeignClient實(shí)例的創(chuàng)建。

在完成創(chuàng)建DemoFeignClient實(shí)例后,我們調(diào)用org.springframework.cloud.openfeign.loadbalancer。

FeignBlockingLoadBalancerClient.execute()執(zhí)行負(fù)載均衡策略時(shí),執(zhí)行到如下代碼塊

Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
                .getSupportedLifecycleProcessors(
                        loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
                        RequestDataContext.class, ResponseData.class, ServiceInstance.class);

"loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class)"邏輯會(huì)獲取LoadBalancer實(shí)例,最終調(diào)用LoadBalancerClientConfiguration.java中的reactorServiceInstanceLoadBalancer()實(shí)現(xiàn)創(chuàng)建負(fù)載均衡實(shí)例邏輯

@Bean
    @ConditionalOnMissingBean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        //創(chuàng)建負(fù)載均衡實(shí)例,而且我們發(fā)現(xiàn)默認(rèn)的負(fù)載均衡實(shí)例是輪詢負(fù)載均衡實(shí)例
        return new RoundRobinLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }

ok,截止到目前為止,我們的負(fù)載均衡實(shí)例已經(jīng)創(chuàng)建完成!

這樣一來,我們通過openfeign進(jìn)行遠(yuǎn)程調(diào)用時(shí),通過下圖的調(diào)用鏈

圖四

FeignInvocationHandler.invoke()->SynchronousMethodHandler.invoke()->org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient.execute()->org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.choose()->org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer.choose(),這樣的調(diào)用鏈最終根據(jù)RoundRobinLoadBalancer.choose()獲取服務(wù)實(shí)例。

public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
                .getIfAvailable(NoopServiceInstanceListSupplier::new);
        //返回服務(wù)實(shí)例
        return supplier.get(request).next()
                .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
    }

拿到服務(wù)實(shí)例后,F(xiàn)eignBlockingLoadBalancerClient.execute()中最終通過LoadBalancerUtils.executeWithLoadBalancerLifecycleProcessing()獲取響應(yīng)結(jié)果!

下面是具體代碼邏輯:

static Response executeWithLoadBalancerLifecycleProcessing(Client feignClient, Request.Options options,
            Request feignRequest, org.springframework.cloud.client.loadbalancer.Request lbRequest,
            org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse,
            Set<LoadBalancerLifecycle> supportedLifecycleProcessors, boolean loadBalanced, boolean useRawStatusCodes)
            throws IOException {
        supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse));
        try {
            //通過openfeign調(diào)用,獲取響應(yīng)結(jié)果
            Response response = feignClient.execute(feignRequest, options);
            if (loadBalanced) {
                supportedLifecycleProcessors.forEach(
                        lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
                                lbRequest, lbResponse, buildResponseData(response, useRawStatusCodes))));
            }
            return response;
        }
        catch (Exception exception) {
            if (loadBalanced) {
                supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
                        new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, lbResponse)));
            }
            throw exception;
        }
    }

以上就是詳解openfeign集成spring cloud loadbalancer實(shí)現(xiàn)負(fù)載均衡流程的詳細(xì)內(nèi)容,更多關(guān)于spring cloud loadbalancer的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • cookie、session和java過濾器結(jié)合實(shí)現(xiàn)登陸程序

    cookie、session和java過濾器結(jié)合實(shí)現(xiàn)登陸程序

    這篇文章主要為大家詳細(xì)介紹了cookie、session和java過濾器結(jié)合實(shí)現(xiàn)登陸程序的具體代碼,感興趣的朋友可以參考一下
    2016-05-05
  • Java接口返回省市區(qū)樹形結(jié)構(gòu)的實(shí)現(xiàn)

    Java接口返回省市區(qū)樹形結(jié)構(gòu)的實(shí)現(xiàn)

    本文主要介紹了Java接口返回省市區(qū)樹形結(jié)構(gòu)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 解析Java中PriorityQueue優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的源碼及用法

    解析Java中PriorityQueue優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的源碼及用法

    優(yōu)先級(jí)隊(duì)列是一種隊(duì)列結(jié)構(gòu),是0個(gè)或多個(gè)元素的集合,每個(gè)元素都有一個(gè)優(yōu)先權(quán),PriorityQueue被內(nèi)置于JDK中,本文就來解析Java中PriorityQueue優(yōu)先級(jí)隊(duì)列結(jié)構(gòu)的源碼及用法.
    2016-05-05
  • SpringBoot選擇自有bean優(yōu)先加載實(shí)現(xiàn)方法

    SpringBoot選擇自有bean優(yōu)先加載實(shí)現(xiàn)方法

    在一些需求中,可能存在某些場(chǎng)景,比如先加載自己的bean,然后自己的bean做一些DB操作,初始化配置問題,然后后面的bean基于這個(gè)配置文件,繼續(xù)做其他的業(yè)務(wù)邏輯。因此有了本文的這個(gè)題目
    2023-03-03
  • Mybatis優(yōu)化檢索的方法詳解

    Mybatis優(yōu)化檢索的方法詳解

    MyBatis是一款優(yōu)秀的基于Java的持久層框架,它可以將 SQL 語句和數(shù)據(jù)庫(kù)中的記錄映射成為 Java 對(duì)象,并且支持靈活的 SQL 查詢語句,在Mybatis中,可以使用動(dòng)態(tài)SQL來靈活構(gòu)造SQL語句,從而滿足各種不同的檢索需求,本文介紹Mybatis如何優(yōu)化檢索,需要的朋友可以參考下
    2024-05-05
  • Java+Selenium實(shí)現(xiàn)文件上傳下載功能詳解

    Java+Selenium實(shí)現(xiàn)文件上傳下載功能詳解

    這篇文章主要介紹了java代碼如何利用selenium操作瀏覽器上傳和下載文件功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2023-01-01
  • 基于Luhn算法的銀行卡校驗(yàn)規(guī)則

    基于Luhn算法的銀行卡校驗(yàn)規(guī)則

    這篇文章主要為大家介紹了基于Luhn算法的銀行卡校驗(yàn)規(guī)則,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Spring中的集合注入代碼實(shí)例

    Spring中的集合注入代碼實(shí)例

    這篇文章主要介紹了Spring中的集合注入代碼實(shí)例,集合注入是指在Spring框架中,通過配置文件或注解的方式將集合類型的數(shù)據(jù)注入到Bean中,集合類型包括List、Set、Map和Properties等,需要的朋友可以參考下
    2023-11-11
  • SpringMVC實(shí)現(xiàn)登錄與注冊(cè)功能的詳細(xì)步驟

    SpringMVC實(shí)現(xiàn)登錄與注冊(cè)功能的詳細(xì)步驟

    本文介紹了如何通過Maven配置依賴,創(chuàng)建前端登錄和注冊(cè)頁面,并實(shí)現(xiàn)后端邏輯,詳細(xì)步驟包括配置文件、創(chuàng)建User類、配置中文過濾器及DispatcherServlet,并使用Spring?MVC和JQuery處理前端請(qǐng)求,需要的朋友可以參考下
    2024-11-11
  • Java在Excel中添加水印的實(shí)現(xiàn)(單一水印、平鋪水印)

    Java在Excel中添加水印的實(shí)現(xiàn)(單一水印、平鋪水印)

    這篇文章主要介紹了Java在Excel中添加水印的實(shí)現(xiàn)(單一水印、平鋪水印),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論