咱們在前面兩篇文章分析了Spring Cloud Eureka 註冊中心和客戶端的源碼,在註冊中心會有不少同應用名的實例組成集羣供客戶端調用,這時咱們就須要負載策略來實現如何請求服務.這時咱們就會用到Spring Cloud Ribbon,它是一個服務請求方應用內嵌的一個組件,並非一個服務,也就是說Eureka客戶端都集成了Ribbon,在這裏不用額外的導入依賴,用法咱們在Ribbon負載均衡---SpringCloud(三)有過介紹,那麼如今咱們來分析一下源碼,看究竟是怎麼實現的;html
咱們利用restTemplate執行一個請求,最後都會經過org.springframework.web.client.RestTemplate#doExecute方法,主要內容以下:web
try { //利用攔截器建立請求 ClientHttpRequest request = createRequest(url, method); if (requestCallback != null) { requestCallback.doWithRequest(request); } //執行請求,負載的功能在這裏面實現 response = request.execute(); handleResponse(url, method, response); if (responseExtractor != null) { return responseExtractor.extractData(response); } else { return null; } }
在前面的使用過程當中,咱們知道Ribbon負載均衡主要依賴於RestTemplate實現的,但RestTemplate其實並非Ribbon的組件,咱們看其所在的包可知,該組件在spring-web包下,也就是說RestTemplate只是被Ribbon利用,用於訪問外部服務的一個方法,真正實現負載均衡的是咱們加上其上面的註解@LoadBalanced;spring
若是你讀了以前分析Spring Cloud Eureka源碼分析,相信對***AutoConfiguration很熟悉了吧,延續以前的一向做風,Spring Cloud Ribbon一樣也有一個 RibbonAutoConfiguration,先來分析其實例化條件:app
@Configuration @ConditionalOnClass({ IClient.class, RestTemplate.class, AsyncRestTemplate.class, Ribbon.class}) @RibbonClients @AutoConfigureAfter(name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration") @AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class}) @EnableConfigurationProperties(RibbonEagerLoadProperties.class) public class RibbonAutoConfiguration { ....省略內部代碼... }
這個應該不用介紹了吧,不過也說一句,主要使得該類被Spring感知到,與@EnableAutoConfiguration配合使用的,若是入口類沒有@EnableAutoConfiguration,則@Configuration不會生效;負載均衡
註解@ConditionalOnClass代表了實例化的條件,當上下文中存在所示的幾個類的時候;這幾個類是幹啥的呢?咱們看一下;異步
/** * A client that can execute a single request. * * @author awang * */ public interface IClient<S extends ClientRequest, T extends IResponse> { /** * Execute the request and return the response. It is expected that there is no retry and all exceptions * are thrown directly. */ public T execute(S request, IClientConfig requestConfig) throws Exception; }
看該類註釋能夠知道,用於訪問服務提供方的一個簡單調用方法, 沒有重試機制,遇到異常則直接拋出,他是一個接口(interface), 也就是說在這裏定義了基礎的執行請求的方法,如有在執行請求有其餘的操做,由其子類實現 工具
由上圖實現接口的子類類名也能夠看出;源碼分析
RestTemplate相信你們確定或多或少的接觸過,或者使用過相似的工具類;她主要用來創建HTTP鏈接,訪問外部服務的同步模板工具,咱們根據該類的Note也可知,ui
* <p><strong>Note:</strong> by default the RestTemplate relies on standard JDK * facilities to establish HTTP connections. You can switch to use a different * HTTP library such as Apache HttpComponents, Netty, and OkHttp through the * {@link #setRequestFactory} property.
這裏還介紹了其餘的相似工具包,你們在項目中也能夠應用,看來源碼也不不是隻介紹關於本身的,也能學到相關其餘的東西;url
RestTemplate提供了六種HTTP方法,Put,Post,Delete,Get,Options,Head,其中區別我就不介紹了,你們能夠點擊或者自由搜索;總之,RestTemplate提供了不少咱們經常使用的模板方法,很靈活,詳細你們打開這個類自由查看吧;
與RestTemplate用法相同,與之不一樣的是AsyncRestTemplate用於異步調用,這裏給你們找了個Demo,自由查看;
/** * A class that can be used to create {@link com.netflix.ribbon.http.HttpResourceGroup}, {@link com.netflix.ribbon.http.HttpResourceGroup.Builder}, * and dynamic proxy of service interfaces. It delegates to a default {@link com.netflix.ribbon.RibbonResourceFactory} to do the work. * For better configurability or in DI enabled application, it is recommended to use {@link com.netflix.ribbon.RibbonResourceFactory} directly. * */
用於自定義配置,細粒度的;
@Configuration @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE }) @Documented @Import(RibbonClientConfigurationRegistrar.class) public @interface RibbonClients { RibbonClient[] value() default {}; Class<?>[] defaultConfiguration() default {}; }
咱們知道,負載均衡的策略有輪詢,隨機,權重等等...而Ribbon默認的是輪詢,若是咱們要指定不一樣的策略,就須要在項目入口類使用這個註解導入配置;而一般咱們的服務調用方會調用不少個服務集羣,而調用每一個服務的時候負載策略都不同,所以該註解內部又提供了@RibbonClient註解;
用法:@RibbonClient用於註解在項目入口類上,name爲服務提供方,value指定自定義負載策略;
@RibbonClients用於整合多個@RibbonClient註解;defaultConfiguration爲默認的負載策略;
具體事例咱們以後再提供;//TODO
說明該配置類實例化在註解中配置類以後,這也能夠理解,EurekaClientAutoConfiguration是Eureka客戶端的配置,而RibbonAutoConfiguration是客戶端的一個組件的配置,確定先有客戶端,若是須要,纔會有Ribbon的配置;
說明該配置類實例化在註解中配置類以前;註解中類作了什麼,咱們接下來展開;
負載均衡同步請求自動配置類
用於指定是否支持部分調用服務RibbonClientde 預加載;
在使用Ribbon的時候,常常會遇到一種狀況就是第一次執行請求超時,這是因爲調用服務的RibbonClient是懶加載的,在第一次請求的時候加載這樣就使得第一次請求的時間會很長,容易超過咱們設定的響應超時時間,從而致使響應超時;經過此項配置能夠避免這種狀況發生;
在這裏經過@EnableConfigurationProperties開啓了這個配置類經過外部配置文件的屬性配置實例化bean的功能,使得該類能夠經過@ConfigurationProperties註解指定配置屬性在配置文件中的前綴,並將其值注入到成員變量,實例化成bean;
待續...