flsh

Ribbon负载均衡

Ribbon

 

Ribbon是什么?

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

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

 

Ribbon能干嘛?

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

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

负载均衡简单分类:

集中式LB

  • 即在服务的消费方和提供方之间使用独立的LB设施
  • 由该设施负责把访问请求通过某种策略转发至服务的提供方!

进程式LB

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

 

Ribbon的初步配置

因为LB(负载均衡)是集成于消费方进程,消费方通过它来获取到服务提供方的地址所以要在客户端(消费端)进行修改。

打开springcloud-consumer-dept-80的工程

pom.xml,添加依赖

复制代码
<!-- eureka-server服务端 -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
<!--         https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
复制代码

application.yml,追加Eureka的服务注册地址


eureka:
client:
register-with-eureka: false  #false表示不向注册中心注册自己
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    #绑定
 

在ConfigBean中getRestTemplate的方法中加上 @LoadBalanced 的注解,表示获得Rest时加入Ribbon的配置

复制代码
@Configuration
public class configBean {
    @Bean
    @LoadBalanced   //Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具

    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
    }
复制代码

在启动类上,添加 @EnableEurekaClient 的注解

@EnableEurekaClient
@SpringBootApplication
public class DeptConsumer80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer80.class,args);
    }
}

并且将DeptConsumerController的 REST_URL_PREFIX 改为  http://SPRINGCLOUD-PROVIDER-DEPT 因为之前的是死的,现在改为动态的。

//    private static final String REST_URL_PREFIX = "http://localhost:8001";
    private static final String REST_URL_PREFIX ="http://SPRINGCLOUD-PROVIDER-DEPT";

 

测试:

先启动3个Eureka集群后,在启动springcloud-provider-dept-8001并注册进eureka在启动DeptConsumer80

访问

http://localhost/consumer/dept/get/1

http://localhost/consumer/dept/list

 

Ribbon负载均衡

 

 

 Ribbon在工作时分成两步

第一步先选择EurekaServer,它优先选择在同一个区域内负载均衡较少的Server。

第二步在根据用户指定的策略,在从server去到的服务注册列表中选择一个地址。 其中Ribbon提供了多种策略,比如轮询(默认),随机和根据响应时间加权重...

 

参考springcloud-provider-dept-8001,新建两份提供者,端口分别为8002,8003,并按照8001的来粘贴文件,复制完后修改启动类名,端口号

 

 

 在数据库中按照db01的样子来新建数据库db02,db03,并修改里面的数据

修改8002/8003的application.yml文件中的端口,数据库连接的库名,实例名也需要修改

//实例名
instance: instance
-id: springcloud-provider-dept-8001 # 重点,和client平级

对外暴露的统一的服务实例名【三个服务名字必须一致!】

spring:
  application:
    name: springcloud-provider-dept

测试:

启动3个Eureka集群配置区

启动3个Dept微服务并都测试通过

http://localhost:8001/dept/list http://localhost:8002/dept/list

http://localhost:8003/dept/list

启动springcloud-consumer-dept-ribbon-80

客户端通过Ribbon完成负载均衡并访问上一步的Dept微服务

http://localhost/consumer/dept/list

小结

Ribbon:就是将查询到的服务发给服务提供者

 

 

自定义Ribbon的数法

Ribbon默认算法是轮询(RandomRule)

修改springcloud-consumer-dept-80模块

在主启动类上添加@RibbonClient()

@RibbonClient(name="SPRINGCLOUD-PROVIDER-DEPT",configuration= MySelfRule.class)

创建MySelfRule类

@Configuration
public class MySelfRule {

    @Bean
    public IRule myRule(){
        return new RandomRule();//Ribbon默认是轮询,我们自定义为随机算法
    }
}

编写自定义的Ribbon,flshRondomRule 类

复制代码
public class flshRondomRule extends AbstractLoadBalancerRule {
    // total = 0 当total数等于5以后,我们指针才能往下走
// index = 0 当前对外提供服务的服务器地址
// 如果total等于5,则index+1,将total重置为0即可!
// 问题:我们只有3台机器,所有total>3 则将total置为0;
    private int total = 0; //总共被调用的次数
    private int currentIndex = 0; //当前提供服务的机器序号!
    //ILoadBalancer选择的随机算法
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;
        while (server == null) {
//查看线程是否中断了
            if (Thread.interrupted()) {
                return null;
            }
//Reachable: 可及;可到达;够得到
            List<Server> upList = lb.getReachableServers(); //活着的服务
            List<Server> allList = lb.getAllServers(); //获取所有的服务
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }
// int index = chooseRandomInt(serverCount); //生成区间随机数!
// server = upList.get(index); //从活着的服务中,随机取出一个
//+=====================================
            if (total<5){
                server = upList.get(currentIndex);
                total++;
            }else {
                total = 0;
                currentIndex++;
                if (currentIndex>=upList.size()){
                    currentIndex = 0;
                }
                server = upList.get(currentIndex);
            }
//+=====================================
            if (server == null) {
                Thread.yield();
                continue;
            }
            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 choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}
复制代码

修改MySelfRule类,将返回结果修改为flshRondomRule的类

public class MySelfRule {
    @Bean
public IRule myRule(){
return new flshRondomRule();//Ribbon默认是轮询,我们自定义为flshRondomRule
}
}

 

posted on   小鱼洗香香  阅读(50)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示