二刷Ribbon源码(下)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 二刷Ribbon源码(下)
public <T> T getInstance(String name, Class<T> type) {
        AnnotationConfigApplicationContext context = getContext(name);
        if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
                type).length > 0) {
            return context.getBean(type);返回bean
        }
        return null;
    }


获取到ILoadBalancer实现,我们就可以调用其chooseServer获得一个服务实例,进行请求了。


ILoadBalancer userLoadBalancer = clientFactory.getLoadBalancer("user");
Server server = userLoadBalancer.chooseServer("default")


3.4 (使用) LoadBalancerClient

LoadBalancerClient封装了SpringClientFactory, 作为负载均衡器客户端,被广泛使用。这个类才是SC-Ribbon的真正负载均衡客户端的入口。

提供了三个方法:


  • 选择服务实例方法;
  • 执行请求方法
  • 重构uri方法。

每个方法都是与负载均衡有关

ServiceInstance choose(String serviceId);
    <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
    URI reconstructURI(ServiceInstance instance, URI original);


LoadBalancerClient作为负载均衡客户端。他的能力完全是建立在以上所有组件的共同努力下实现的。


public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;
    public void doStuff() {
        ServiceInstance instance = loadBalancer.choose("stores");
        URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
        // ... do something with the URI
    }
}


3.SC-Ribbon与eureka一起使用又发生了什么


1.配置层面:

SpringCloudRibbonEureka一起使用时,会使用@RibbonClients为所有的服务的负载均衡替换一些默认组件(更换组合套件)


@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
@ConditionalOnBean(SpringClientFactory.class)
@ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true)
@AutoConfigureAfter(RibbonAutoConfiguration.class)
@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class)
public class RibbonEurekaAutoConfiguration {
}
----------------------------
@Configuration
@CommonsLog
public class EurekaRibbonClientConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public IPing ribbonPing(IClientConfig config) {
        NIWSDiscoveryPing ping = new NIWSDiscoveryPing();//
        ping.initWithNiwsConfig(config);
        return ping;
    }
    @Bean
    @ConditionalOnMissingBean
    public ServerList<?> ribbonServerList(IClientConfig config) {
        DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(
                config);
        DomainExtractingServerList serverList = new DomainExtractingServerList(
                discoveryServerList, config, this.approximateZoneFromHostname);
        return serverList;
    }
}    


  • IPing: 使用NIWSDiscoveryPing这个实现


  • ServerList:使用了DomainExtractingServerListDomainExtractingServerList代理了DiscoveryEnabledNIWSServerListDiscoveryEnabledNIWSServerList存储的服务列表都从EurekaClient本地缓存里取到的。(取操作是PollingServerListUpdater,定时执行的)


public class DiscoveryEnabledNIWSServerList extends AbstractServerList<DiscoveryEnabledServer>{
private List<DiscoveryEnabledServer> obtainServersViaDiscovery() {
    EurekaClient eurekaClient = eurekaClientProvider.get();
    List<InstanceInfo> listOfInstanceInfo = eurekaClient.getInstancesByVipAddress(vipAddress, isSecure, targetRegion);
    ....
}
}


2.使用层面:

没啥变化,就是使用LoadBalancerClient来使用负载均衡获取一个Server。


4.Resttemplate 如何具有负载均衡能力


Resttemplate 具有负载均衡能力,其本质还是通过使用LoadBalancerClient来实现。

如何实现呢?

这就涉及到两个知识点:

  • Resttemplate相关体系:
  • @LoadBalanced 注解。


Resttemplate 是有拦截器的概念的 。也就是说在真正发起请求之前,会走一些拦截器。这就给负载均衡选择一个Server提供了机会。


@LoadBalanced 注解就是给其修饰的Resttemplate实例,注入LoadBalancerInterceptor拦截器。此拦截器就是通过LoadBalancerClient来实现了负载均衡


public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
    private LoadBalancerClient loadBalancer;
    ...
}


具体可阅读我的其他文章

发送http请求(1):发送http请求的几种方式

发送http请求(2):RestTemplate发送http请求

@LoadBalanced注解的RestTemplate拥有负载均衡的能力


5.总结


文本从介绍负载均衡的几个组件开始,由底层讲到了Resttemplate原理。打开了Resttemplate发起负载均衡请求的黑盒。顺着这条线,只要仔细研读各个部分的知识点。

你会感叹开源框架的大厦的建立,为我们省去了多少开发工作。

我们不应该是停留在使用的阶段,还应该深入去了解底层框架的原理,这样你才会在大厦之上更进一层。


参考链接:

https://www.jianshu.com/p/73c117fbfe10

https://blog.csdn.net/hry2015/article/details/78357990


如果本文任何错误,请批评指教,不胜感激 !

如果文章哪些点不懂,可以联系我交流学习!


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