9.与springcloud结合

一、简介

使用ribbon,一般都是和springcloud结合使用,springcloud提供了胶水代码来整合ribbon。

二、接口

ServiceInstanceChooser该接口只有一个方法:

public interface ServiceInstanceChooser {
    /**
     * Choose a ServiceInstance from the LoadBalancer for the specified service
     * @param serviceId the service id to look up the LoadBalancer
     * @return a ServiceInstance that matches the serviceId
     */
    ServiceInstance choose(String serviceId);
}

其实现类如下:
在这里插入图片描述
我们可以看到好多Retry开头的,这些类的实例会被自动注入,如果class路径发现org.springframework.retry.support.RetryTemplate的话。

也就是说,默认情况下,并没有开启retry功能。如果需要开启retry机制,需要引入以下配置:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

这里对于retry相关的不再多写,详细请参考重试

那么,默认的就只有一个类了,就是RibbonLoadBalancerClient。

三、实现

这里看一下如何实现choose的:

  1. 首先对于每个serviceId,spring会创建一个单独的ILoadBalancer。
  2. 之后调用ILoadBalancer.chooseServer(“default”),这里就对应到了负载均衡器的ZoneAwareLoadBalancer.choose流程。

四、与RestTemplate整合

参照[结合ribbonLoadBalanced]的部分,整个调用过程如下:
在这里插入图片描述
可以看到,调用链还是比较长的,最终会调用到ILoadBalancer,实现负载均衡。

五、与Feign整合

从spring-cloud-netflix-core/META-INF/sping.factories可以看到这个自动注入类:FeignRibbonClientAutoConfiguration,它的condition如下:

@ConditionalOnClass({ ILoadBalancer.class, Feign.class })

也就是说,如果classpath存在ribbon的依赖和Feign的依赖,将启用该配置。

那么注入的feign使用的http客户端是哪个?

1.HttpURLConnection的
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
        SpringClientFactory clientFactory) {
    return new LoadBalancerFeignClient(new Client.Default(null, null),
            cachingFactory, clientFactory);
}
2.httpclient的
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
protected static class HttpClientFeignLoadBalancedConfiguration {
    @Autowired(required = false)
    private HttpClient httpClient;
    @Bean
    @ConditionalOnMissingBean(Client.class)
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
            SpringClientFactory clientFactory) {
        ApacheHttpClient delegate;
        if (this.httpClient != null) {
            delegate = new ApacheHttpClient(this.httpClient);
        }
        else {
            delegate = new ApacheHttpClient();
        }
        return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
    }
}
3.okhttp的
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true)
protected static class OkHttpFeignLoadBalancedConfiguration {
    @Autowired(required = false)
    private okhttp3.OkHttpClient okHttpClient;
    @Bean
    @ConditionalOnMissingBean(Client.class)
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
            SpringClientFactory clientFactory) {
        OkHttpClient delegate;
        if (this.okHttpClient != null) {
            delegate = new OkHttpClient(this.okHttpClient);
        }
        else {
            delegate = new OkHttpClient();
        }
        return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
    }
}

httpclient和okhttp都有static修饰,那么就会比HttpURLConnection先加载。

而httpclient和okhttp取决于pom里依赖了那个jar,例如依赖feign-okhttp则为okhttp:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

依赖feign-httpclient则为httpclient:


<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

无论用哪个http客户端,可以看到,最终都传给了LoadBalancerFeignClient,该类最终会调用到ILoadBalancer的choose方法,流程如下图:
在这里插入图片描述
到这里看到ILoadBalancer就清楚了,跟之前的负载均衡器结合起来了

发布了62 篇原创文章 · 获赞 23 · 访问量 15万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章