Ribbon客户端负载均衡

本文详细介绍了Spring Cloud Ribbon的工作原理及使用方法,包括如何配置基于客户端的负载均衡,自定义负载均衡策略等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码地址:https://gitee.com/peachtec/springcloud

什么是Ribbon

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

Ribbon能干啥

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

  1. 集中式LB
    即在服务的消费方和提供方之间使用独立的LB设施,如nginx反向代理服务器,由设施负责吧访问通过某种策略转发到服务的提供方
  2. 进程式LB
    将LB逻辑集成到消费方,消费方从服务注册中心获知哪些地址可用,然后自己再从这些地址中选出一个合适的服务器
    Ribbon属于进程内LB,它只是一个类库,集成在消费方进程,消费者通过它获取到服务提供的地址
      
怎么使用Ribbon

  Ribbon是一个类库,集成在消费方进程,所以我们只需要在消费者项目中去配置Ribbon,代码依旧使用之前的项目,端口为80的模块为我的消费者模块

  1. 导入jar包依赖
<!-- Ribbon -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- Eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  1. 编写配置
#Eureka 客户端配置
eureka:
  client:
    register-with-eureka: false # 不向Eureka注册自己
    service-url: # 注册中心地址
      defaultZone: http://eureka7002:7002/eureka/,http://eureka7003:7003/eureka/,http://eureka7004:7004/eureka/
  1. 配置负载均衡,通过一个注解进行配置
@Configuration
public class RestTemplateConfig {
    //配置负载均衡实现RestTemplate
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  1. 在主启动类中开启Eureka
@SpringBootApplication
@EnableEurekaClient
public class Resumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(Resumer_80.class, args);
    }
}
  1. 编写控制层接口,通过负载均衡访问的地址应该是一个变量,通过服务名访问
    在这里插入图片描述
/**
 * 通过负载均衡访问的地址应该是一个变量,通过服务名访问
 */
private static final String URL_PREFIX = "http://SPRINGCLOUD-SERVER/dept";

@GetMapping("/get/{id}")
public Dept getDeptById(@PathVariable Integer id) {
    return restTemplate.getForObject(URL_PREFIX + "/get/" + id, Dept.class);
}

  上面把Eureka和Ribbon整合在消费者模块了,但是实际上还没有真正的使用负载均衡,接下就实现负载均衡,将服务提供模块、数据库进行复制,基本上和之前的8001的服务提供模块一样。

  1. 创建服务需要的数据库,我现在的电脑同时跑三个服务提供者服务应该能抗住
drop database if exists db01;
create database if not exists db01 default character set utf8mb4 collate utf8mb4_general_ci;
use db01;

drop table if exists `dept`;
create table if not exists `dept`
(
    `id`        int primary key auto_increment comment '编号',
    `name`      varchar(60) not null comment '部门',
    `db_source` varchar(20) not null comment '数据库名'
) comment '部门表';
insert into dept (name, db_source)
values ('开发部', database()),('人事部', database()),('市场部', database()),('销售部', database()),('运维部', database()),('行政部', database());


drop database if exists db02;
create database if not exists db02 default character set utf8mb4 collate utf8mb4_general_ci;
use db02;

drop table if exists `dept`;
create table if not exists `dept`
(
    `id`        int primary key auto_increment comment '编号',
    `name`      varchar(60) not null comment '部门',
    `db_source` varchar(20) not null comment '数据库名'
) comment '部门表';
insert into dept (name, db_source)
values ('开发部', database()),('人事部', database()),('市场部', database()),('销售部', database()),('运维部', database()),('行政部', database());

drop database if exists db03;
create database if not exists db03 default character set utf8mb4 collate utf8mb4_general_ci;
use db03;

drop table if exists `dept`;
create table if not exists `dept`
(
    `id`        int primary key auto_increment comment '编号',
    `name`      varchar(60) not null comment '部门',
    `db_source` varchar(20) not null comment '数据库名'
) comment '部门表';
insert into dept (name, db_source)
values ('开发部', database()),('人事部', database()),('市场部', database()),('销售部', database()),('运维部', database()),('行政部', database());
  1. 创建服务提供者模块8002和8003端口,其代码参考8001模块,需要注意项目名需要保持一致,否则就是其他的服务了
spring:
  application:
    name: springcloud-server
  1. 将所有的服务提供者启动,可以再Eureka的后台查看是否被注册进去了
    在这里插入图片描述
  2. 测试结果,可以看到,每次去访问,都是从不同的数据库获取到的数据,并且默认的算法为轮训
    在这里插入图片描述
      除了默认的负载均衡算法,我们还可以自定义实现负载均衡算法,去实现IRule接口类,官方给了我们以下的实现
  3. AvailabilityFilteringRule:先过滤跳闸的服务,对剩下的进行轮训
  4. RoundRobinRule:轮训,默认算法
  5. RandomRule:随机
  6. WeightedResponseTimeRule:权重
  7. RetryRule:会先按照轮训获取服务,如果服务获取失败,会在执行的时间内进行重试
    在这里插入图片描述
    示例:每个服务访问3次,然后换下一个服务
public class MyRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
    @Override
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }
    /**
     * 需求
     * 每个服务访问3次,然后换下一个服务
     */
    private int total = 0;//执行的次数
    private int index = 0;//服务的下标

    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();
            if (allList.size() == 0) {
                return null;
            }
            if (total < 3) {
                total++;
            } else {
                total = 0;
                index++;
                if (index >= upList.size()) {
                    index = 0;
                }
            }
            server = upList.get(index);
            if (server == null) {
                Thread.yield();
            } else {
                if (server.isAlive()) {
                    return server;
                }
                server = null;
                Thread.yield();
            }
        }
        return server;
    }
}

然后,将我们自定义的算法注册到spring中,并在启动类中进行配置

//注册
@Configuration
public class RuleConfig {
    @Bean
    public IRule myrule(){
        return new MyRule();
    }
}
//启动类中配置
@SpringBootApplication
@EnableEurekaClient
//在微服务启动时加载自定义的Ribbon类configuration指定配置类
@RibbonClient(name = "SPRINGCLOUD-SERVER", configuration = MyRule.class)
public class Resumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(Resumer_80.class, args);
    }
}

注意,Ribbon的自定义配置不能放在和启动类同级的包中
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

華小灼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值