服务调用Ribbon,LoadBalance,Feign

服务调用Ribbon、Fegin
Ribbon实现负载均衡的原理
1:LoadBalancerAutoConfiguration这个类,这个类主要做的就是把LoadBalancer拦截器封装到RestTemplte拦截器集合里面去。
2:然后在代码里面调用restTemplate.getForObject或者其他方法的时候,就会调用到这个拦截器。
3:在LoadBalancer拦截器类中,就会调用intercept方法,这个方法就会通过execute方法获取负载均衡器以及通过负载均衡算法和得到的servicename去获取一台具体的服务。然后通过http调用。
4:而且ribbon会定时的去更新Nocas中的服务注册中心将其保存在本地,而且在负载均衡真正调用之前的时候也会去更新。
Fegin
1:从@EnableFeginClients注解看,这个注解里面有一个Import注解@Import(FeginClientRegistrat.class);这个类的方法registerFeginClients方法就能扫描主启动类包同机以及下级包中所有符合@FeginClient的类注入到容器当中。
2:然后loadBalance通过jdk动态代理最总生成LoadBalanceFeginClient,这个类中的execute方法中最终去调用我们的ribbon实现负载均衡。

@SpringBootApplication
@EnableFeignClients/此注解/
public class  OrderFeignMain80 {
   
    public static void main(String[] args) {
   
        SpringApplication.run(OrderFeignMain80.class,args);
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.cloud.openfeign;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;

@Retention(RetentionPolicy.RUNTIME)
@Target({
   ElementType.TYPE})
@Documented
@Import({
   FeignClientsRegistrar.class})//此注解
public @interface EnableFeignClients {
   
    String[] value() default {
   };

    String[] basePackages() default {
   };

    Class<?>[] basePackageClasses() default {
   };

    Class<?>[] defaultConfiguration() default {
   };

    Class<?>[] clients() default {
   };
}

FeignClientsRegistrar类

public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
   
        ClassPathScanningCandidateComponentProvider scanner = this.getScanner();
        scanner.setResourceLoader(this.resourceLoader);
        Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FeignClient.class);//此方法
        Class<?>[] clients = attrs == null ? null : (Class[])((Class[])attrs.get("clients"));
        Object basePackages;
        if (clients != null && clients.length != 0) {
   
            final Set<String> clientClasses = new HashSet();
            basePackages = new HashSet();
            Class[] var9 = clients;
            int var10 = clients.length;

            for(int var11 = 0; var11 < var10; ++var11) {
   
                Class<?> clazz = var9[var11];
                ((Set)basePackages).add(ClassUtils.getPackageName(clazz));
                clientClasses.add(clazz.getCanonicalName());
            }

            AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
   
                protected boolean match(ClassMetadata metadata) {
   
                    String cleaned = metadata.getClassName().replaceAll("\\$", ".");
                    return clientClasses.contains(cleaned);
                }
            };
            scanner.addIncludeFilter(new FeignClientsRegistrar.AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
        } else {
   
            scanner.addIncludeFilter(annotationTypeFilter);
            basePackages = this.getBasePackages(metadata);
        }

        Iterator var17 = ((Set)basePackages).iterator();

        while(var17.hasNext()) {
   
            String basePackage = (String)var17.next();
            Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
            Iterator var21 = candidateComponents.iterator();

            while(var21.hasNext()) {
   
                BeanDefinition candidateComponent = (BeanDefinition)var21.next();
                if (candidateComponent instanceof AnnotatedBeanDefinition) {
   
                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition)candidateComponent;
                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
                    Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
                    Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
                    String name = this.getClientName(attributes);
                    this.registerClientConfiguration(registry, name, attributes.get("configuration"));
                    this.registerFeignClient(registry, annotationMetadata, attributes);
                }
            }
        }

    }

相关推荐

  1. 【微服务服务调用

    2024-01-22 07:44:02       60 阅读
  2. dubbo服务调用过程

    2024-01-22 07:44:02       28 阅读
  3. 服务调用使用

    2024-01-22 07:44:02       69 阅读
  4. 服务调用Ribbon,LoadBalance,Feign

    2024-01-22 07:44:02       48 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-22 07:44:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-22 07:44:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-22 07:44:02       82 阅读
  4. Python语言-面向对象

    2024-01-22 07:44:02       91 阅读

热门阅读

  1. js实例继承的例子和优缺点

    2024-01-22 07:44:02       46 阅读
  2. neo4j jdk17下 dump 报错

    2024-01-22 07:44:02       48 阅读
  3. 多层感知机实战

    2024-01-22 07:44:02       52 阅读
  4. 深度学习 pytorch的使用(张量1)

    2024-01-22 07:44:02       43 阅读
  5. 解决org.apache.jasper.JasperException异常

    2024-01-22 07:44:02       50 阅读
  6. 源码分享-golang的BMP文件读写库

    2024-01-22 07:44:02       58 阅读
  7. SpringBoot整理-Spring Boot配置

    2024-01-22 07:44:02       52 阅读
  8. 本地仓库如何与远程仓库进行关联

    2024-01-22 07:44:02       57 阅读
  9. SQL Server 恢复软件

    2024-01-22 07:44:02       52 阅读