【SpringCloud】Ribbon服務調用(六)


Ribbon介紹

  Spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端負載均衡的工具

  Ribbon是Netflix發布的開源項目,主要功能是提供客戶端的軟件負載均衡算法和服務調用。Ribbon客戶端組件提供一系列完善的配置項如連接超時、重試等。簡單的說,就是在配置文件中列出Load Balance(簡稱LB)后面所有的機器,Ribbon會自動的幫組你基於某種規則(如簡單輪詢,隨機連接等)去連接這些機器,我們很容易使用Ribbon實現自定義的負載均衡算法

  LB負載均衡(Load Balance)

  簡單的說就是將用戶的請求平攤到分配到多個服務上,從而達到系統的HA(高可用)。

  常見的負載均衡有軟件Nginx、LVS、硬件FS等

  Ribbon本地負載均衡客戶端 VS Nginx服務端負載均衡區別

  Nginx是服務器負載均衡,客戶端所有請求都會教給Nginx,然后由nginx實現轉發請求,即負載均衡是由服務端實現的

  Ribbon本地負載均衡,在調用微服務接口時候,會在注冊中心上獲取注冊信息服務列表之后緩存到JVM本地,從而本地實現RPC遠程調用技術

  官網:https://github.com/Netflix/ribbon

Ribbon使用

  1、搭建項目、參考【SpringCloud】服務提供者集群與服務發現Discovery(三) 的示例

    采用Eureka作為注冊中心,且有2個服務提供者

    架構如下:

    

  2、Ribbon依賴,依賴如下:

1 <dependency>
2     <groupId>org.springframework.cloud</groupId>
3     <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
4     <version>2.2.2.RELEASE</version>
5     <scope>compile</scope>
6 </dependency>

    通過查看示例項目,調用者order項目依賴,發現在Eureka依賴中,默認含有依賴Ribbon的依賴

       

  3、查看RibbonClientConfiguration.java,Ribbon自動裝載類。

 1 @Configuration(proxyBeanMethods = false)
 2 @EnableConfigurationProperties
 3 @Import({ HttpClientConfiguration.class, OkHttpRibbonConfiguration.class,
 4         RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class })
 5 public class RibbonClientConfiguration {
 6 
 7     ...
 8 
 9     // 自動注入IRule接口用來代表負責負載均衡的策略
10     @Bean
11     @ConditionalOnMissingBean
12     public IRule ribbonRule(IClientConfig config) {
13         if (this.propertiesFactory.isSet(IRule.class, name)) {
14             return this.propertiesFactory.get(IRule.class, config, name);
15         }
16         ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
17         rule.initWithNiwsConfig(config);
18         return rule;
19     }
20 
21     // 自動注入ILoadBalance接口用來代表負責均衡的操作
22     @Bean
23     @ConditionalOnMissingBean
24     public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
25             ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
26             IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
27         if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
28             return this.propertiesFactory.get(ILoadBalancer.class, config, name);
29         }
30         return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
31                 serverListFilter, serverListUpdater);
32     }
33 
34     ...
35 }

     其中自動注入IRule接口用來代表負責負載均衡的策略(默認策略:ZoneAvoidanceRule),和自動注入ILoadBalance接口用來代表負責均衡的操作(默認均衡:ZoneAwareLoadBalancer)

  4、查看ILoadBalance接口(負責均衡的操作)

    繼承關系如下:

    

    內容如下:

 1 public interface ILoadBalancer {
 2 
 3     public void addServers(List<Server> newServers);
 4 
 5     // 根據key選擇一個服務
 6     public Server chooseServer(Object key);
 7 
 8     public void markServerDown(Server server);
 9 
10     public List<Server> getServerList(boolean availableOnly);
11 
12     public List<Server> getReachableServers();
13 
14     public List<Server> getAllServers();
15 }

 

  5、查看IRule接口(負責均衡的策略)

    實現關系:

    

    內容如下:

1 public interface IRule{
2 
3     // 根據key選擇一個服務
4     public Server choose(Object key);
5     
6     public void setLoadBalancer(ILoadBalancer lb);
7     
8     public ILoadBalancer getLoadBalancer();    
9 }

    通過查看實例類,可以看到具體的實現了,可以知道負責均衡的策略

  6、Ribbon工作原理

    查看LoadBalancerAutoConfiguration自動配置類

 1 @Configuration(proxyBeanMethods = false)
 2 @ConditionalOnClass(RestTemplate.class)
 3 @ConditionalOnBean(LoadBalancerClient.class)
 4 @EnableConfigurationProperties(LoadBalancerRetryProperties.class)
 5 public class LoadBalancerAutoConfiguration {
 6 
 7     
 8     ...
 9 
10 
11     @Configuration(proxyBeanMethods = false)
12     @ConditionalOnClass(RetryTemplate.class)
13     public static class RetryInterceptorAutoConfiguration {
14 
15         @Bean
16         @ConditionalOnMissingBean
17         public RetryLoadBalancerInterceptor ribbonInterceptor(
18                 LoadBalancerClient loadBalancerClient,
19                 LoadBalancerRetryProperties properties,
20                 LoadBalancerRequestFactory requestFactory,
21                 LoadBalancedRetryFactory loadBalancedRetryFactory) {
22             return new RetryLoadBalancerInterceptor(loadBalancerClient, properties,
23                     requestFactory, loadBalancedRetryFactory);
24         }
25 
26         // RestTemplate定制器
27         @Bean
28         @ConditionalOnMissingBean
29         public RestTemplateCustomizer restTemplateCustomizer(
30                 final RetryLoadBalancerInterceptor loadBalancerInterceptor) {
31             return restTemplate -> {
32                 List<ClientHttpRequestInterceptor> list = new ArrayList<>(
33                         restTemplate.getInterceptors());
34                 list.add(loadBalancerInterceptor);
35                 // 給restTemplate,設置攔截器
36                 restTemplate.setInterceptors(list);
37             };
38         }
39 
40     }
41 
42 }

    其中自動配置了一個LoadBalancerInterceptor,LoadBalancerInterceptor是個ClientHttpRequestInterceptor客戶端請求攔截器。它的作用是在客戶端發起請求之前攔截,進而實現客戶端的負載均衡。

    以下是RestTemplate注入,加@LoadBalanced,的配置方法

 1 @Configuration
 2 public class AppConfig {
 3 
 4     /**
 5      * 注入restTemplate,請用請求rest接口
 6      * @return
 7      */
 8     @Bean
 9     // 標注此注解后,RestTemplate就具有了客戶端負載均衡能力
10     // 負載均衡技術依賴於的是Ribbon組件~
11     // RestTemplate都塞入一個loadBalancerInterceptor 讓其具備有負載均衡的能力
12     @LoadBalanced
13     public RestTemplate restTemplate(){
14         return new RestTemplate();
15     }
16 }

   7、測試Ribbon,是否根據對於的負責均衡的策略,實現負載

    1)調試模式啟動項目,使用地址:http://localhost:8000/consumer/payment/get/1,進行訪問

    返回內容為提供者2個節點分別交替返回的,到達負載均衡目的。

    2)在ZoneAvoidanceRule類中添加斷點,通過運行程序,可以看到程序會運行到ZoneAvoidanceRule類中。

自帶負載均衡規則說明

策略名 策略聲明 策略描述 實現說明
BestAvailableRule public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 選擇一個最小的並發請求的server 逐個考察Server,如果Server被tripped了,則忽略,在選擇其中ActiveRequestsCount最小的server
AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 過濾掉那些因為一直連接失敗的被標記為circuit tripped的后端server,並過濾掉那些高並發的的后端server(active connections 超過配置的閾值) 使用一個AvailabilityPredicate來包含過濾server的邏輯,其實就就是檢查status里記錄的各個server的運行狀態
WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根據相應時間分配一個weight,相應時間越長,weight越小,被選中的可能性越低。 一個后台線程定期的從status里面讀取評價響應時間,為每個server計算一個weight。Weight的計算也比較簡單responsetime 減去每個server自己平均的responsetime是server的權重。當剛開始運行,沒有形成statas時,使用roubine策略選擇server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 對選定的負載均衡策略機上重試機制。 在一個配置時間段內當選擇server不成功,則一直嘗試使用subRule的方式選擇一個可用的server
RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式輪詢選擇server 輪詢index,選擇index對應位置的server
RandomRule public class RandomRule extends AbstractLoadBalancerRule 隨機選擇一個server 在index上隨機,選擇index對應位置的server
ZoneAvoidanceRule public class ZoneAvoidanceRule extends PredicateBasedRule 復合判斷server所在區域的性能和server的可用性選擇server 使用ZoneAvoidancePredicate和AvailabilityPredicate來判斷是否選擇某個server,前一個判斷判定一個zone的運行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用於過濾掉連接數過多的Server。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM