SpringCloud-Ribbon (三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dtttyc/article/details/88853525

前言

阅读之前先阅读
https://blog.csdn.net/dtttyc/article/details/88817129

Ribbon是什么

  1. 基于Netflix Ribbon 实现的一套客户端 负载均衡工具
  2. 实现负载均衡算法-客户端
  3. 根据不同的配置规则到不同的服务端

什么是LB(load Balance)

LB一般是在分布式或者集群中提及, 为了就是可以让不同服务访问均匀,或者根据不同配置可以路由到不同服务,一般我们常见的负载均衡就是nginx

LB的形式

LB 他的形式一般有两种,Ribbon就属于进程内的LB,LB把业务逻辑集成到消费方,由消费方去注册中心(Eureka)获取使用哪些服务,

  1. LB集中式
  2. 进程内LB

Ribbon使用步骤

首先我们先简单的使用一下Ribbon

Ribbon的配置一般都是在消费端
  1. 使用@loadBalance 负载均衡
   @Bean
   @LoadBalanced  //负载均衡
   public RestTemplate getRestTemplate(){
       return new RestTemplate();
   }

首先说明以下@bean是要和@Configuration一起使用的,相当于我们的application.yml文件

//他们两个表示的意思是一样的
   @Bean
  public UserService getUserService(){
      return new UserServiceIml();
    }
  <bean id="userService" class="com.atguitu.springcloud/user.iml/">

  1. 整合Eureka

    在springboot的启动 项上使用 @EnableEurekaClient

  2. 使用默认的负载均衡算法

    当我们不指定负载均衡算法的时候默认使用的是轮询算法

  3. 指定使用那个服务,name是服务的名称, configurtion表示加载那个类(一会说到,一般是自定义配置企业的负载均衡类)

    @RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class)
  1. 消费端
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "consumer/dept/list")
    public List<Dept> list(Dept dept) {
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
    }
  1. 跳转路由服务端实现

Ribbon 负载均衡算法种类

  1. RandomRule
 随机访问
  1. AvailabilityFilteringRule
 过滤: 
    1.  多次出现故障的服务
    2 . 并发连接数超过阀值的服务
    3. 根据剩余的服务列表按照最开始默认的轮询机制进行访问
  1. RetryRule
当遇到服务失败的时候他会主动的跳过,并且可以制定时间重新检查服务是否已经恢复
  1. WeightedResponseTimeRule
平均响应时间计算权重
1. 响应越快服务权重越大,选中率越高
2. 建议,最开始的时候先别使用平均响应时间计算权重,因为这个时候统计信息可能不够全面,所以一般在最开始的时候可以使用轮询机制,等到信息你全面的时候可以使用weightResponseTimeRule
  1. BestAvailableRule
过滤被多次访问并且故障的服务, 然后选择一个并发量下的服务
  1. ZoneAvoidanceRule
默认规则, 复合判断server所在区域性能和server的可用性选择服务器

Ribbon 自定义配置

1 基本AbstractLoadBalancerRule (其实把源码拿过来就行了)
源码地址

https://github.com/Netflix/ribbon

自定义的配置的业务是假设我们让3台服务分别访问5次,然后切换下一台服务

     //total ===5 一会才可以替换机器
    // index = 3 表示服务只有3台
    // total ===5的时候我们至为0,然后index=3
    private int total = 0;
    private int currentIndex = 0;

    /**
     * Randomly choose from all living servers
     */

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        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) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }
                  //修改的内容
            if(total<5){
                server = upList.get(currentIndex);
                total++;
            }else {
                total = 0;
                currentIndex ++;
                if (currentIndex>=upList.size()){
                    currentIndex=0;
                }
            }

//            int index = chooseRandomInt(serverCount);  随机获取索引值index
//            server = upList.get(index);  得到服务器实例

            if (server == null) {
                /*
                 * The only time this should happen is if the server list were
                 * somehow trimmed. This is a transient condition. Retry after
                 * yielding.
                 */
                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }

            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }

        return server;

    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

2 . 把刚刚自定义的配置加载到spring容器里面

/**
 * @Author: judy
 * @Description: 自定义Ribbon
 * @Date: Created in 11:50 2019/3/27
 */
@Configuration
public class MySelfRule {
    @Bean
    public IRule myRule() {
        return new RandomRule_ZY();
    }

}
注意刚刚的那两个方法不能放在服务的启动项里面,也就是在springbootapplication下面, 官方已经明确指出,原因是因为@ComponentScan,否则不会认为你是自己自定义的ribbon
  1. 启动的时候加载类
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class) 

Ribbon 整体情况

LoadBalancerClient
当她在初始化的时候会去服务注册列表,并且通过10s一次向EurekaClient发送ping命令, 判断服务是否可以用
IRule
如果有了服务注册列表她会通过IRule 进行负载均衡

1loadBalancerClient------>IloadBalancer---->IRule,Ping ---->EurekaClient

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dtttyc/article/details/88853525