SpringCloud(四) : Riddon負載均衡

簡介

Ribbon是一個客戶端IPC庫,在雲中進行了測試。它提供瞭如下特性 spring

  • 負載均衡緩存

  • 容錯性 app

  • 異步反應模型中的多協議(HTTP、TCP、UDP)支持 負載均衡

  • 緩存和批量處理 異步

 

基礎使用

1.導入依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

2.在RestTemplate Bean加上註解@LoadBalanced

@Bean
@LoadBalanced //默認採用的是RoundRobinRule,輪詢策略
public RestTemplate restTemplate(){
    return new RestTemplate();
}

 

自定義負載均衡策略

源碼分析

Riddon的負載均衡策略ide

經過查看Riddon的源碼能夠看出,Riddon的負載均衡策略類都繼承了AbstractLoadBalancerRule源碼分析

package com.netflix.loadbalancer;

import com.netflix.client.IClientConfigAware;

public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware {
    private ILoadBalancer lb;

    public AbstractLoadBalancerRule() {
    }

    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb = lb;
    }

    public ILoadBalancer getLoadBalancer() {
        return this.lb;
    }
}

AbstractLoadBalancerRule實現了Riddon的負載均衡方法接口 IRule測試

package com.netflix.loadbalancer;

public interface IRule {
    Server choose(Object var1);

    void setLoadBalancer(ILoadBalancer var1);

    ILoadBalancer getLoadBalancer();
}

因此咱們只要繼承AbstractLoadBalancerRule,重寫IRule接口裏的choose方法,並把自定義負載均衡策略的實現類經過配置類@Bean以IRule類型返回就能夠自定義負載均衡策略了this

自定義負載均衡策略實現

配置類不能放在@SpringBootApplication應用同級目類下,不然它由全部@RibbonClients共享,就達不到特殊化指定的目的了spa

CustomConfiguration類必須是@Configuration類,但請注意,對於主應用程序上下文,它不在@ComponentScan中。不然,它由全部@RibbonClients共享。若是您使用@ComponentScan(或@SpringBootApplication),則須要採起措施避免將其包括在內(例如,能夠將其放在單獨的,不重疊的程序包中,或指定要在@ComponentScan)。

  • 建立負載均衡策略的配置類
@Configuration
public class MyRuleConfig {
    @Bean
    public IRule ribbonRule(){
        return new MyRule();
    }
}
  • 建立負載均衡策略的實現類
public class MyRule extends AbstractLoadBalancerRule {

    private static Logger log = LoggerFactory.getLogger(MyRule.class);
    private int total = 0;
    private int index = 0;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
    @Override
    public Server choose(Object o) {
        return this.choose(this.getLoadBalancer(),o);
    }

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;

            while (server == null) {
                if (Thread.interrupted()) {
                    return null;
                }

                List<Server> upList = lb.getReachableServers();//獲取可得到到的服務,即沒有故障能夠運行的服務
                List<Server> allList = lb.getAllServers();//獲取全部服務
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }

                //自定義負載均衡方法,每一個服務執行3次,依次輪詢
                if (total<3){
                    server = (Server) upList.get(index);//根據索引從可得到的服務中獲取服務
                    total++;
                }else {
                    total=0;
                    if (index>=upList.size()-1){
                        index=0;
                    }else {
                        index++;
                    }
                }

                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }
}
  • 在主配置類上添加@RibbonClient
@Configuration
//name爲服務提供者配置的spring.application.name,configuration爲自定義負載均衡的配置類
@RibbonClient(name = "SPRINGCLOUD-PROVIDER", configuration = MyRuleConfig.class) 
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

 

 

個人我的博客站

相關文章
相關標籤/搜索