首页 > 编程语言 > 详细

SpringCloud(5)-Ribbon

时间:2020-04-22 21:19:42      阅读:72      评论:0      收藏:0      [点我收藏+]

SpringCloud(5)-Ribbon

Ribbon简介

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

负载均衡(Load Balance)

  • LB,即负载均衡(Load Balance) ,在微服务或分布式集群中经常用的一种应用。

  • 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高可用)。

  • 常见的负载均衡软件有Nginx, Lvs 等等。

  • dubbo、 SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。

  • 负载均衡简单分类:

    1. 集中式LB

    即在服务的消费方和提供方之间使用独立的LB设施,如Nginx(反向代理服务器),由该设施负责把访问请求通过某种策略转发至服务的提供方!

    1. 进程式LB

    将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。Ribbon就属于进程式LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!

集成Ribbon

  1. 在原本的客户端springcloud-consumer-dept-80项目的pom文件中添加Ribbon依赖与Eureka依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  1. 在application.yml中配置Eureka
eureka:
  instance:
    hostname: localhost #eureka服务端实例名称
  client:
    register-with-eureka: false #表示是否向eureka注册自己
    fetch-registry: false #如果为false表示自己为注册中心
    service-url:  #监控页面
      defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
  1. 在主启动类上开启EurekaClient
@EnableEurekaClient
@SpringBootApplication
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}
  1. 修改原本的BeanConfig
//配置负载均衡实现RestTemplate
@Bean
@LoadBalanced //Ribbon
public RestTemplate restTemplate(){
    return new RestTemplate();
}
  1. 修改DeptConsumerController中原本的REST_PATH_PREFIX为application name,基于服务名去访问。客户端不用关心服务提供者的IP地址与端口号了!(原本:private static final String REST_PATH_PREFIX="http://localhost:8001")
private static final String REST_PATH_PREFIX="http://springcloud-provider-dept";
  1. 启动项目,访问http://localhost/consumer/dept/all测试:

技术分享图片

Ribbon实现负载均衡

  1. 新建两个数据库sc02,sc03,数据与sc01除db_source其余一致。

  2. 新建两个Maven项目springcloud-provider-dept-8002,springcloud-provider-dept-8003。复制springcloud-provider-dept-8001项目中的所有内容。

  3. 修改springcloud-provider-dept-8002,springcloud-provider-dept-8003的application.yml中的端口号,连接的数据库名字与Eureka的默认描述信息。

  4. 保证3个服务提供者的application name一致。

spring:
  application:
    name: springcloud-provider-dept
  1. 记得修改mapper里面查询对应数据库的dept表。
  2. 编写对应的启动类。
  3. 启动项目,访问http://localhost:7001/:

技术分享图片

访问http://localhost/consumer/dept/all,多次刷新页面,发现查询了不同的数据库(默认算法为简单轮询):

技术分享图片

技术分享图片

技术分享图片

自定义负载均衡算法

  1. 选择服务消费者springcloud-consumer-dept-80,在com.yinrz包下新建一个包myrule,编写自定义的负载均衡算法类MyRule:
//自定义负载均衡算法:一个服务连续访问5次后,换下一个服务
public class MyRule extends AbstractLoadBalancerRule {
    public MyRule(){
    }
    private int total=0;
    private int current=0;

    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    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;
                }

//========================核心算法开始==============================
                System.out.println(111);
                if(total<=5){
                    server = upList.get(current);
                    total++;
                }else {
                    total=0;
                    current++;
                    if (current>=upList.size()){
                        current=0;
                    }
                    server = upList.get(current);
                }

//========================核心算法结束==============================


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

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

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }

}
  1. 在myrule包下写一个配置类MyRuleConfig:
@Configuration
public class MyRuleConfig {

    @Bean
    public IRule myRule(){
        return new MyRule();
    }
}
  1. 在主启动类上添加注解@RibbonClient:
@EnableEurekaClient
@SpringBootApplication
@RibbonClient(name = "springcloud-provider-dept",configuration = MyRuleConfig.class)//在微服务启动的时候就能加载我们自定义的Ribbon类
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}
  1. 运行3个服务提供者,Eureka服务端,服务消费者项目,访问http://localhost/consumer/dept/all测试。

SpringCloud(5)-Ribbon

原文:https://www.cnblogs.com/yinrz/p/12755734.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!