二刷Ribbon源码(中)

简介: 二刷Ribbon源码(中)

3.1 (配置)默认的配置RibbonClientConfiguration


此配置类也是作为一个默认配置类存在,也就是在你不配置任何东西是SpringCloud-Ribbon默认装载的核心组件的组合,

相比于Netflix Ribbon项目DefaultClientConfigImpl 的提供的默认组件为


image.png


3.2 (配置)自定义配置


本着可扩展原则: SpringCloudRibbon也要提供个性化配置功能。


3.2.1 注解式配置类

这里涉及两个注解:@RibbonClient@RibbonClients (注意有个s

  • 这两注解类功能是,被他们注解的类会通过某种机制RibbonClientConfiguration替换默认的配置
  • 这两个注解的区别是:一个覆盖的是单个服务的某个组件,一个针对多个服务

使用方式如下:我把user服务负载均衡的IPing 组件替换为我的MyPingUrl

Configuration
@RibbonClient(name = "user", configuration = UserConfiguration.class)
public class UserRibbonConfiguration {
}
@Configuration
protected static class UserConfiguration{
    @Bean
    public IPing ribbonPing() {
        return new MyPingUrl();
    }
}

注意 添加UserConfiguration中的配置。UserConfiguration必须使用@Configuration进行声明,而且不能放在可以被main application context的@ComponentScan或@SpringBootApplication扫描到的地方,防止该配置被所有的@RibbonClient共享

如果想把所有服务的负载均衡的的IPing 组件替换为我的MyPingUrl

@RibbonClient(defaultConfiguration = UserConfiguration.class)
public class UserRibbonConfiguration {
}


工作原理

这两个注解的工作原理是:通过引入RibbonClientConfigurationRegistrar注册器,将配置类注册为一个RibbonClientSpecification

@Configuration
@Import(RibbonClientConfigurationRegistrar.class)//这里
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RibbonClient {
}
//注册器
public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
        private void registerClientConfiguration(BeanDefinitionRegistry registry,
            Object name, Object configuration) {
            //注册为一个RibbonClientSpecification
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
                .genericBeanDefinition(RibbonClientSpecification.class);
        builder.addConstructorArgValue(name);
        builder.addConstructorArgValue(configuration);
        registry.registerBeanDefinition(name + ".RibbonClientSpecification",
                builder.getBeanDefinition());
    }
}

RibbonClientSpecification: 直译为客户端规范,对,你的个性化配置被解析为一个客户端规范

举例说明为:

  • A服务,B服务使用同一个个性化配置,A,B服务就有一个RibbonClientSpecification规范
  • C服务使用一个个性化配置,C服务就有一个RibbonClientSpecification规范

这个规范是如何生效的呢?见下文


3.2.1 配置文件里配置:

另一种就是直接在spring体系内的配置文件中配置

application.yml

api-user:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList

在这些属性中定义的类优先于使用@RibbonClient(configuration=MyRibbonConfig.class)定义的bean和由Spring Cloud Netflix提供的默认值。

说了配置,在讲讲使用层面的工作


使用层面的工作

负载均衡功能的使用其实就在ILoadBalancer这个统筹组件上。所谓使用,其实就是就在这个ILoadBalancer上。


3.3 (使用) SpringClientFactory


SpringClientFactory使用工厂模式对外提供:根据serviceId获取IClient, ILoadBalance, ILoadBalanceContext等对象的服务。

这里我们只关注ILoadBalance的获取。

SpringClientFactory 为每个服务创建一个独立的上下文,并在其中加载对应的配置及Ribbon核心接口的实现类。创建逻辑在其父类NamedContextFactory


public abstract class NamedContextFactory{
    private Map<String, C> configurations = new ConcurrentHashMap<>();
    private Class<?> defaultConfigType;
    //创建上下文
    protected AnnotationConfigApplicationContext createContext(String name) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        if (this.configurations.containsKey(name)) {
            for (Class<?> configuration : this.configurations.get(name)
                    .getConfiguration()) {
                context.register(configuration);
            }
        }
        for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
            if (entry.getKey().startsWith("default.")) {
                for (Class<?> configuration : entry.getValue().getConfiguration()) {
                    context.register(configuration);
                }
            }
        }
        context.register(PropertyPlaceholderAutoConfiguration.class,
                this.defaultConfigType);
        context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
                this.propertySourceName,
                Collections.<String, Object> singletonMap(this.propertyName, name)));
        if (this.parent != null) {
            // Uses Environment from parent as well as beans
            context.setParent(this.parent);
        }
        context.refresh();
        return context;
    }
}


这里有两个点:

  1. 根据传入服务serverId 创建一个AnnotationConfigApplicationContext,装载属于他自己的负载均衡套件。不同的服务有不同的上下文,里面存储的是属于他的负载均衡套件组合


  1. 服务的负载均衡套件组合方式。是上文提到的两种配置方式决定的。也就是configurationsdefaultConfigType两个属性所代表的规范。
private Map<String, C> configurations = new ConcurrentHashMap<>();
    private Class<?> defaultConfigType;//代表默认的组件组合
  • configurations :代表的是个性化配置的套件规范。上文提到的RibbonClientSpecification
  • defaultConfigType :代表的就是sc-ribbon的默认配置类RibbonClientConfiguration

当我们调用SpringClientFactory.getLoadBalancer方法获取一个负载均衡器实例时, 本质就是在这个服务对应的上下文中取出属于他的ILoadBalancer实现。


相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 算法 Java
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
|
10月前
|
设计模式 负载均衡 Apache
SpringCloud源码剖析-Zuul使用Ribbon负载均衡-RibbonRoutingFilter
RibbonCommandContext 在run方法中构建了一个 RibbonCommandContext Ribbon的上下文对象,然后调用 forward 方法转发请求 ,通过 setResponse方法设置结果
91 0
|
10月前
|
设计模式 负载均衡 Apache
二十.SpringCloud源码剖析-Zuul使用Ribbon负载均衡-RibbonRoutingFilter
经过前面几章的学习,我们对Zuul的的详细执行流程,以及内置的Filter都有了一些认识,本篇文章是针对RibbonRoutingFilter做一个详细的分析,跟一下它是如何使用Ribbon对下游的微服务进行负载均衡的。注意:这篇文章是在 《zuul的执行流程》基础上进行延伸的,另外Ribbon的原理见:《Ribbon负载均衡原理》
|
10月前
|
缓存 负载均衡 算法
十五.SpringCloud源码剖析-Ribbon工作流程
Ribbon是由Netflix公司开源的一个客户端负载均衡器,主要功能是实现服务之间的负载均衡调用,内置丰富的负载均衡算法,本章意在探讨Ribbon的核心工作流程,Ribbon基本使用请看《[SpringCloud极简入门-客户端负载均衡Ribbon](https://blog.csdn.net/u014494148/article/details/105002095)》
|
10月前
|
缓存 负载均衡 算法
十四.SpringCloud源码剖析-Ribbon的初始化配置
前面我们分析了Eureka的源码,接下来这一章我们来研究一下Ribbon,本篇文章主要是对Ribbon的相关组件做一个认识,以及它的初始化配置做一个分析。
|
缓存 负载均衡 Java
深入剖析ribbon源码
深入剖析ribbon源码
137 0
深入剖析ribbon源码
|
12月前
|
Java Spring
Spring Cloud Alibaba源码 - 21 Ribbon 源码解析
Spring Cloud Alibaba源码 - 21 Ribbon 源码解析
99 0
|
负载均衡 Cloud Native 算法
【微服务七】Ribbon负载均衡策略之BestAvailableRule源码深度剖析
【微服务七】Ribbon负载均衡策略之BestAvailableRule源码深度剖析
310 0
【微服务七】Ribbon负载均衡策略之BestAvailableRule源码深度剖析
|
存储 负载均衡 Cloud Native
【云原生&微服务八】Ribbon负载均衡策略之WeightedResponseTimeRule源码剖析(响应时间加权)
【云原生&微服务八】Ribbon负载均衡策略之WeightedResponseTimeRule源码剖析(响应时间加权)
196 0
【云原生&微服务八】Ribbon负载均衡策略之WeightedResponseTimeRule源码剖析(响应时间加权)
|
负载均衡 Cloud Native Java
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)
237 0
【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)