瘋狂創客圈 Java 高併發【 億級流量聊天室實戰】實戰系列 【博客園總入口 】html
瘋狂創客圈 正在進行分佈式和高併發基礎原理 的研習,好比下面的一些基礎性的內容:java
2、高併發 springcloud + zookeeper 秒殺github
以及有關Springcloud 幾篇核心、重要的文章:面試
2、Feign Ribbon Hystrix 三者關係 , 史上最全 深度解析spring
3、SpringCloud gateway 詳解 , 史上最全apache
5、常識糾錯:Feign 默認不用 短鏈接服務器
6、Feign 核心原理,圖解併發
前面介紹到了經常使用的Feign客戶端實現類,大體以下:
(1) Client.Default類:默認的 feign.Client 客戶端實現類,內部使用HttpURLConnnection 完成HTTP URL請求處理;
(2) ApacheHttpClient 類:內部使用 Apache httpclient 開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類;
(3) OkHttpClient類:內部使用 OkHttp3 開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類。
(4) LoadBalancerFeignClient 類:這是一個特殊的 feign.Client 客戶端實現類。內部先使用 Ribbon 負載均衡算法計算server服務器,而後使用包裝的 delegate 客戶端實例,去完成 HTTP URL請求處理。
Feign 在啓動的時候,有兩個與feign.Client 客戶端實例相關的自動配置類,根據多種條件組合,去建立不一樣類型的 客戶端Spring IOC容器實例。
Feign有兩個與Client相關的自動配置類:
(1)org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration
(2)org.springframework.cloud.openfeign.FeignAutoConfiguration
第一個自動配置類,可以配置具備負載均衡能力的FeignClient容器實例;第二自動配置類,只能配置最原始的FeignClient容器實例。
具有負載均衡能力的 FeignClient 容器實例,所對應的類型爲 LoadBalancerFeignClient 類型。前面講到,在SpringCloud中,爲了達到高可用,一個微服務至少應該部署兩個以上節點,從這個角度來講,LoadBalancerFeignClient 容器實例,已經成爲事實上的標配。
事實上,第一個自動配置類 FeignRibbonClientAutoConfiguration,在容器的裝配次序上,是優先於第二個自動配置類 FeignAutoConfiguration 的。具體能夠參見其源碼,節選以下:
import com.netflix.loadbalancer.ILoadBalancer; //…. @ConditionalOnClass({ILoadBalancer.class, Feign.class}) @Configuration @AutoConfigureBefore({FeignAutoConfiguration.class}) // 本配置類具有優先權 @EnableConfigurationProperties({FeignHttpClientProperties.class}) @Import({ HttpClientFeignLoadBalancedConfiguration.class, //配置:包裝ApacheHttpClient實例的負載均衡客戶端 OkHttpFeignLoadBalancedConfiguration.class, //配置:包裝OkHttpClient 實例的負載均衡客戶端 DefaultFeignLoadBalancedConfiguration.class //配置:包裝Client.Default 實例的負載均衡客戶端 }) public class FeignRibbonClientAutoConfiguration { //空的構造器 public FeignRibbonClientAutoConfiguration() { } //…. }
從源碼中能夠看到,FeignRibbonClientAutoConfiguration 的自動配置有兩個前提條件:
(1)當前的類路徑中,存在 ILoadBalancer.class 接口
(2)當前的類路徑中,存在 Feign.class 接口
在這裏,重點說一下 ILoadBalancer.class 接口,該接口處於 ribbon 的jar包中。若是須要在類路徑中導入該jar包,則須要在Maven的pom.xml文件中,增長 ribbon 的相關依賴,具體以下:
<!-- ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
爲了加深你們對客戶端負載均衡的理解,這裏將 ILoadBalancer.class 接口的兩個重要的抽象方法列出來,具體以下:
package com.netflix.loadbalancer; import java.util.List; public interface ILoadBalancer { // 經過負載均衡算法計算server服務器 Server chooseServer(Object var1); // 取得所有的服務器 List<Server> getAllServers(); //… }
FeignRibbonClientAutoConfiguration 自動配置類,並無直接配置LoadBalancerFeignClient 容器實例,而是使用@Import註解,經過導入其餘配置類的方式,完成 LoadBalancerFeignClient 客戶端容器實例的配置。
分別導入瞭如下三個自動配置類:
(1) HttpClientFeignLoadBalancedConfiguration.class
該配置類,負責配置一個包裝 ApacheHttpClient 實例的 LoadBalancerFeignClient負載均衡客戶端。
(2) OkHttpFeignLoadBalancedConfiguration.class
該配置類,負責配置一個包裝 OkHttpClient 實例的 LoadBalancerFeignClient負載均衡客戶端。
(3) DefaultFeignLoadBalancedConfiguration.class
該配置類,負責配置一個包裝 Client.Default 實例的 LoadBalancerFeignClient負載均衡客戶端。
首先來看如何配置一個包裝 ApacheHttpClient 實例的負載均衡容器實例。這個IOC實例的配置,由 HttpClientFeignLoadBalancedConfiguration 自動配置類完成的,其源碼節選以下:
@Configuration @ConditionalOnClass({ApacheHttpClient.class}) @ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true ) class HttpClientFeignLoadBalancedConfiguration { //空的構造器 HttpClientFeignLoadBalancedConfiguration() { } @Bean @ConditionalOnMissingBean({Client.class}) public Client feignClient( CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory, HttpClient httpClient) { ApacheHttpClient delegate = new ApacheHttpClient(httpClient); return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); // 進行包裝 } //…省略不相干的代碼 }
首先,來看源碼中的 feignClient(…)方法,分爲兩步:
(1)建立一個 ApacheHttpClient 類型的 feign.Client客戶端實例,該實例的內部使用 Apache httpclient 開源組件完成HTTP URL請求處理;
(2)建立一個 LoadBalancerFeignClient 負載均衡客戶端實例,將 ApacheHttpClient 實例包裝起來,而後返回LoadBalancerFeignClient 客戶端實例,做爲 feign.Client 類型的Spring IOC 容器實例。
而後,再看類 HttpClientFeignLoadBalancedConfiguration 上的兩個重要的註解:
(1)@ConditionalOnClass(ApacheHttpClient.class)
(2)@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
這兩個條件的含義爲:
(1)必須知足 ApacheHttpClient.class 在當前類路徑中存在;
(2)必須知足工程配置文件中 feign.httpclient.enabled 配置項的值爲 true ;
若是以上兩個條件同時知足,則 HttpClientFeignLoadBalancedConfiguration 自動配置工做就會啓動。
如何驗證呢?
首先在工程配置文件中,將配置項 feign.httpclient.enabled 的值,設置爲 false 。而後,在 HttpClientFeignLoadBalancedConfiguration 的 feignClient(…)方法內的某行打上斷點,從新啓動項目,注意觀察會發現,整個啓動過程當中,斷點沒有被命中。接下來,將配置項 feign.httpclient.enabled 的值設置爲 true,再一次啓動項目,斷點被命中。由此,能夠驗證 HttpClientFeignLoadBalancedConfiguration 自動配置類被啓動。
爲了知足 @ConditionalOnClass(ApacheHttpClient.class) 的條件要求,因爲ApacheHttpClient類的位置處於feign-httpclient相關的jar包中,因此,須要在pom文件加上 feign-httpclient 以及httpclient 組件相關的 Maven 依賴,具體以下:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> <version>9.5.1</version> <!--<version>${feign-httpclient.version}</version>--> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency>
對於 feign.httpclient.enabled 配置項設置,根據 @ConditionalOnProperty 註解的屬性matchIfMissing=true 可知,這個能夠不用配置,在默認的狀況下就爲 true。換句話說,若是不作特別的配置,feign.httpclient.enabled 配置項的值,默認爲 true。
接下來,來看如何配置一個包裝 OkHttpClient 實例的負載均衡容器實例。這個IOC實例的配置,由 OkHttpFeignLoadBalancedConfiguration 自動配置類完成的,其源碼節選以下:
@Configuration @ConditionalOnClass({OkHttpClient.class}) @ConditionalOnProperty("feign.okhttp.enabled") class OkHttpFeignLoadBalancedConfiguration { //空的構造器 OkHttpFeignLoadBalancedConfiguration () { } @Bean @ConditionalOnMissingBean({Client.class}) public Client feignClient( CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory, HttpClient httpClient) { OkHttpClient delegate = new OkHttpClient (httpClient); return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); // 進行包裝 } //…省略不相干的代碼 }
首先,來看源碼中的 feignClient(…)方法,分爲兩步:
(1)建立一個 OkHttpClient 類型的 feign.Client客戶端實例,該實例的內部使用 OkHttp3 開源組件完成HTTP URL請求處理;
(2)建立一個 LoadBalancerFeignClient 負載均衡客戶端實例,將 OkHttpClient實例包裝起來,而後返回LoadBalancerFeignClient 客戶端實例,做爲 feign.Client 類型的Spring IOC 容器實例。
而後,再看類 OkHttpFeignLoadBalancedConfiguration 上的兩個重要的註解:
(1)@ConditionalOnClass(OkHttpClient.class)
(2)@ConditionalOnProperty("feign.okhttp.enabled")
這兩個條件的含義爲:
(1)必須知足 OkHttpClient.class 在當前類路徑中存在;
(2)必須知足工程配置文件中 feign.okhttp.enabled 配置項的值爲 true 。
若是以上兩個條件同時知足,則 OkHttpFeignLoadBalancedConfiguration 自動配置工做就會啓動。
爲了知足 @ConditionalOnClass(OkHttpClient.class) 的條件要求,因爲OkHttpClient.class 類的位置處於 feign-okhttp 相關的jar包中,因此,須要在pom文件加上 feign-okhttp 以及 okhttp3 相關的 Maven 依賴。具體以下:
<!-- OkHttp --> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency> <!-- feign-okhttp --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
對於 feign.okhttp.enabled 配置項設置,在默認的狀況下就爲 false。也就是說,若是須要使用feign-okhttp,則必定須要作特別的配置,在工程配置文件中,加上 feign.okhttp.enabled 配置項的值,而且值必須爲 true。若是須要使用 feign-okhttp,工程配置文件的配置項大體以下:
feign.httpclient.enabled=false feign.okhttp.enabled=true
最後,來看如何配置一個包裝默認Client.Default 客戶端實例的負載均衡容器實例。這個IOC實例的配置,由 DefaultFeignLoadBalancedConfiguration 自動配置類所完成的。該配置類,也就是 FeignRibbonClientAutoConfiguration 配置類經過 @import 註解所導入的第3個配置類。
DefaultFeignLoadBalancedConfiguration 的源碼節選以下:
package org.springframework.cloud.openfeign.ribbon; //…省略import @Configuration class DefaultFeignLoadBalancedConfiguration { DefaultFeignLoadBalancedConfiguration() { } @Bean @ConditionalOnMissingBean public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) { return new LoadBalancerFeignClient( new Default((SSLSocketFactory)null, (HostnameVerifier)null), cachingFactory, clientFactory); } }
經過源碼能夠看出,若是前面的兩個配置類的條件沒有知足,feign.Client 的 IOC 容器實例沒有裝配,則:
(1) 建立一個 Client.Default 默認客戶端實例,該實例的內部,使用HttpURLConnnection 完成URL請求處理;
(2) 建立一個 LoadBalancerFeignClient 負載均衡客戶端實例,將 Client.Default 實例包裝起來,而後返回LoadBalancerFeignClient 客戶端實例,做爲 feign.Client 類型的Spring IOC 容器實例。
具體,請關注 Java 高併發研習社羣 【博客園 總入口 】
最後,介紹一下瘋狂創客圈:瘋狂創客圈,一個Java 高併發研習社羣 【博客園 總入口 】
瘋狂創客圈,傾力推出:面試必備 + 面試必備 + 面試必備 的基礎原理+實戰 書籍 《Netty Zookeeper Redis 高併發實戰》
Java (Netty) 聊天程序【 億級流量】實戰 開源項目實戰
瘋狂創客圈 【 博客園 總入口 】
y Zookeeper Redis 高併發實戰](https://www.cnblogs.com/crazymakercircle/p/11397271.html)》
[外鏈圖片轉存中...(img-Xmc93wKV-1575216360903)]
Java (Netty) 聊天程序【 億級流量】實戰 開源項目實戰
瘋狂創客圈 【 博客園 總入口 】