上節課我們一起學習了使用Ribbon做為負載均衡的工具,這節我們一起學習如何通過代碼自定義配置Ribbon。
我們還是先從官網文檔開始學習,如下圖所示,我們可以搞一個測試配置類,來驗證是否真的可以通過代碼來自定義配置Ribbon,但文檔明确給出了警告:即這個測試配置類不能放在@ComponentScan所掃描的目前包下以及子包下,否則我們自定義的這個配置類就會被所有的Ribbon用戶端所共享,也就是說我們達不到特殊化定制的目的了。
那麼,哪個類用到了@ComponentScan注解了呢?由于Ribbon是負責用戶端負載均衡的,是以我們要配置的自然就是我們的movie微服務了,movie微服務的啟動類中有一個@SpringBootApplication注解,我們按Ctrl再點選SpringBootApplication類進入該注解類。
SpringBootApplication接口類如下圖所示,可以看到在該接口類上有我們所說的@ComponentScan注解,這也就意味着,凡是該啟動類所在的包(com.itmuch.cloud)以及該包的子包都将被所有Ribbon用戶端所共享。
是以,為了讓我們所定義的配置類不在@ComponentScan的掃描範圍下,我們便需要在包"com.itmuch.cloud"之上來放置,這裡我選擇了放在com.itmuch.config包下,如下圖所示。
這裡大家可能注意到了,在官方文檔中,TestConfiguration類上方有一行注解@RibbonClient,如下圖所示。(這裡需要說明的是:FooConfiguration.class應該換成我們定義的類TestConfiguration)
我把它放到啟動類上了,如下圖所示,這樣做的目的無非是為了在啟動該微服務的時候就能去加載我們的自定義Ribbon配置類,進而使配置生效。(這裡有一點需要說明的是,@RibbonClient(name="microservice-provider-user"這個microservice-provider-user不是随便寫的,而是注冊到Eureka發現元件上的微服務服務端,意思是要對所有工程名為microsevice-provider-user的服務提供者進行負載均衡管理)
Eureka發現元件上目前注冊的微服務如下,可以看到我們的服務提供者是"microservice-provider-user"。
現在既然要自定義負載均衡的方式,那麼我們便需要看一看負載均衡的方式都有哪些,我們先按Ctrl鍵再用滑鼠放到configuration上點選進入該類。
我們可以看到如下圖所示的内容,在注釋中明确告訴我們使用的是RibbonClientConfiguration,我們還是Ctrl并單擊進入該類。
我們會看到如下圖所示的内容,在該類中有所有的自定義的負載均衡政策。
我們Ctrl+F搜尋"ribbonrule"便可以看到如下圖所示的方法。
我們就借用一下該方法到我們的TestConfiguration類中,如下圖所示。大家應該看到了,我們注入的config類有警告,其實這是不影響運作的,不必理會它。如果大家實在看着别扭,可以參考:http://blog.csdn.net/u012453843/article/details/54906905這篇部落格進行處理,就不會報警告了。
剛才我們在Eureka服務發現元件上隻注冊了一個服務提供者(user微服務),為了可以看出來負載均衡的不同效果,我們再起一個名為microservice-provider-user的服務提供者,隻是端口需要改下,另外再起兩個名為microservice-provider-user的服務提供者,注意端口不能一樣。其實要做到這些非常簡單,我們隻需要修改user微服務的application.yml檔案就可以了。我們已經注冊的那個user微服務的端口号是7900,那麼我們第二個名為microservice-provider-user的微服務的端口便改為7901。
改完之後,我們到user微服務的啟動類去啟動7901端口的user微服務。啟動完之後,我們再到Eureka首頁看下目前注冊的微服務,發現已經有兩個名為microservice-provider-user的微服務注冊進來了,隻是端口不一樣而已。
接下來我們再啟動兩個名為microservice-provider-user2的微服務,這樣做是為了更好的看清楚ribbon的負載均衡政策是不是按照服務注冊名來區分的。如下圖所示,我們改端口号為7902,名稱為microservice-provider-user,改完後我們到啟動類啟動該微服務。(同理,我們修改端口為7903,name依然叫microservice-provider-user2,再起一個)
起完之後,我們再來看一下Eureka首頁,如下圖所示,可以看到,服務名為microservice-provider-user的微服務有兩個,名為microservice-provider-user2的微服務也有兩個。
為了能夠更友善的看出不同政策的負載均衡的效果,我們在movie微服務中添加了些代碼,友善我們測試,如下圖所示。
this.loadBalancerClient.choose("microservice-provider-user");可以随機擷取名為microservice-provider-user的一個微服務的執行個體,并用該執行個體做相應的事情。
下面我們重新開機movie微服務,然後到位址欄輸入:http://localhost:8010/test并連續重新整理多次。
然後我們到movie的控制台下看看負載均衡的調用情況,如下圖所示,我們通過觀察可以發現,服務一的調用是沒有規律的(即端口7900和7901出現的次數沒有規律可言,說明是随機政策。而服務二則不同,它出現的非正常律,7903和7902依次出現數量相等,說明這是輪詢政策)這也說明了,我們自定義的随機政策起作用了,而且隻作用在了名為microservice-provider-user的微服務上,并未影響名為microservice-provider-user2的微服務。
既然說TestConfiguration在com.itmuch.cloud下會有問題,那麼我們就來試試,先把TestConfiguration放到com.itmuch.cloud.config目錄下。
我們再運作MicroserviceSimpleConsumerMovieApplication,會出現如下所示錯誤:
2017-12-02 11:20:32.956 INFO 4872 --- [ main] croserviceSimpleConsumerMovieApplication : No active profile set, falling back to default profiles: default
refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testConfiguration': Unsatisfied dependency expressed through field 'config'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.netflix.client.config.IClientConfig' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
要解決這個問題,我們隻需要将IClientConfig config注釋掉,把ribbonRule方法中的參數去掉。
然後我們重新啟動movie服務,然後通路http://localhost:8010/test,多次重新整理,然後我們來看結果,如下圖所示,可以看到user和user2都成随機的了。說明這時TestConfiguratioin已經作用在user和user2兩個上面了(雖然我們隻配置了一個user并沒有配置user2)。是以這樣做是不合适的。
要實在想把TestConfiguratioin放到com.itmuch.cloud及其子目錄下,也是可以的。首先我們建立一個注解類如下圖所示:
接着我們在MicroserviceSimpleConsumerMovieApplication啟動類上面加上@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExcludeFromComponentScan.class)})如下圖所示。
下面我還需要在TestConfiguration類上方添加我們剛才寫的注解@ExcludeFromComponentScan,如下圖所示。
好,下面我們來重新啟動movie服務,然後多次通路http://localhost:8010/test,運作結果如下圖所示,可以看到user是随機的,user2是輪詢的,說明把TestConfiguration類放到@ComponentScan掃描包下面也不是不可以,隻是需要排除掉它就可以了。