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();
    }
}

 

 

个人我的博客站

相关文章
相关标签/搜索