SpringCloud学习—Ribbon:负责均衡及Ribbon

ribbno是什么?

        Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具
        简单的说,Ribbon是Netflix发布的开源项目, 主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。 Ribbon的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer (简称LB: 负载均衡)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法!

ribbon能干什么?

        LB,即负载均衡(Load Balance) ,在微服务或分布式集群中经常用的一种应用。
        负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高可用) .
        常见的负载均衡软件有 Nginx,Lvs等等
        dubbo、SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义

负载均衡简单分类:

集中式LB
        即在服务的消费方和提供方之间使用独立的LB设施,如Nginx, 由该设施负责把访问请求通过某种策略转发至服务的提供方!
进程式LB
        将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
        

        Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!

在的消费者客户端集成ribbon

在消费者 配置Eureka和Ribbon负载均衡依赖

pom.xml


        
            org.springframework.cloud
            spring-cloud-starter-eureka
            1.4.6.RELEASE
        
        
        
            org.springframework.cloud
            spring-cloud-starter-ribbon
            1.4.6.RELEASE
        

修改application.yml配置

server:
  port: 8004

eureka:
  client:
    register-with-eureka: false #不向Eureka中注册自己
    service-url:
      defaultZone: http://localhost:8005/eureka/

在配置类的RestTemplate方法加上注解@LoadBalanced实现ribbon的负载均衡

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced //配置负载均衡实现RestTemplate
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }


}

配置完成后,我们就可以通过服务名来访问其他服务。把提供者的地址,改成服务名后,启动代码访问接口

private static final String REST_URL_PERFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

SpringCloud学习—Ribbon:负责均衡及Ribbon_第1张图片

当前提供方只有一个项目,当前体会不到负载均衡,所以需要创建多个提供方来实现负载均衡

再创建两个提供者以及两个数据库,新建的提供者的结构与第一个提供者的相同

添加依赖,与第一个提供者的依赖相同

新建两个提供者的application.yml如下(只是端口号不同即可)

server:
  port: 8006


mybatis:
  type-aliases-package: com.zlt.springcloud.pojo
  mapper-locations: classpath:mapper/*.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?
    username: root
    password: 123456
    hikari:
      pool-name: DateHikariCP
      # ???????
      minimum-idle: 5
      # ???????,??600000(10??)
      idle-timeout: 1800000
      # ????????10
      maximum-pool-size: 10
      # ?????????????
      auto-commit: true
      # ?????????0???????1800000?30???
      max-lifetime: 18000000
      # ?????????30000?30??
      connection-timeout: 30000

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8005/eureka/
  instance:
    instance-id: springcloud-provider-8006 #修改eureak上默认描述的信息

info:
  app.name: springcloud02
  company.name: hahaha

添加完成后。启动服务端、三个提供者、以及消费者。

在eureka注册中心可以看到,一个服务中有三个实例

SpringCloud学习—Ribbon:负责均衡及Ribbon_第2张图片

localhost:8004/consumer/dept/list 访问,多次刷新,我们这次可以直观的看到显示不同服务的数据,这次我们可直观的感受到负载均衡的应用。 这是ribbon默认的算法,通过轮询访问实例。

SpringCloud学习—Ribbon:负责均衡及Ribbon_第3张图片

 SpringCloud学习—Ribbon:负责均衡及Ribbon_第4张图片

SpringCloud学习—Ribbon:负责均衡及Ribbon_第5张图片

Ribbon负载均衡的算法模式

  • RoundRobinRule 轮询(默认模式)
  • RandomRule 随机
  • RetryRuke 先按轮询获取服务,如果服务获取失败,则会在指定的时间内进行重试
  • AvailabilityFilteringRule  先过滤掉跳闸的或者访问很慢的服务,对剩下的服务轮询

 如何使用其他模式呢?

在消费者的配置类里面进行配置,配置一个IRule类,里面返回需要的模式就好了,比如这里是随机模式

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced //配置负载均衡实现RestTemplate
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    @Bean
    public IRule myRule(){
        return new RandomRule();
    }


}

启动服务器、提供者、消费者,然后访问3次http://localhost:8004//consumer/getlist

发现访问三个实例的顺序是随机的

SpringCloud学习—Ribbon:负责均衡及Ribbon_第6张图片 

 

 

自定义规则

在主目录外 创建myrule文件包 

在myrule下创建MyRule配置类

在myrule包下创建DiyRandomRule,双击shift搜索 RandomRule 全部复制,改为自己自定义算法负载均衡

public class DiyRandomRule extends AbstractLoadBalancerRule {
    //代码全是复制的 DiyRandomRule.class的,自定义负载均衡需要自己修改
 
    //当前自定义负载均衡:
    //每个服务访问5次。换下一个服务
    //total=0,默认=0,如果=5,指向下一个服务节点
    //index=0,默认0,如果total=5,则inedx+1
 
    private int totla=0;//被调用的次数
    private int currentIndex=0;//当前是谁在提供服务
    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 upList = lb.getReachableServers();//获得活着的服务
                List allList = lb.getAllServers();//获得全部的服务
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }
 
                //int index = this.chooseRandomInt(serverCount);//生成区间随机数
                //server = (Server) upList.get(index);//从活着的服务中,随机获取一个
 
               //================自定义负载均衡算法==================
                if(totla<5){
                    server = upList.get(currentIndex);
                    totla++;
                }else{
                    totla=0;
                    currentIndex++;
                    if (currentIndex>=upList.size()){//当前节点大于活着的数量
                        currentIndex = 0;
                    }
                    server=upList.get(currentIndex);//从活着的服务中,获取指定的服务来进行操作
                }
               //====================================================
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
 
                    server = null;
                    Thread.yield();
                }
            }
 
            return server;
        }
    }
 
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
 
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }
 
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}

在消费者启动器上添加自定义负载均衡配置引用的@RibbonClien注解

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}

重启服务, 访问多次http://localhost:8004//consumer/getlist

我们可看到页面每刷新五次值会更改 

你可能感兴趣的:(spring,cloud,学习,ribbon)