SpringCloud-Ribbon负载均衡简介与简单配置

本文介绍了Spring Cloud Ribbon的功能,如何通过引入依赖和自定义配置实现负载均衡,重点讲解了轮询算法的工作原理及如何手动模拟自定义负载均衡。通过实例演示了如何在Spring Boot应用中使用Ribbon进行服务发现和负载均衡。
摘要由CSDN通过智能技术生成


前言

看前需要先看作者的上一篇博客:
点这里->SpringCloud-Eureak服务注册中心

一、Ribbon是什么

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

二、Ribbon使用

1.引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

如果已经引入了spring-cloud-starter-netflix-eureka-client 依赖则不需要再次引入Ribbon依赖,因为 eureka-client 已经包括Ribbon了

2.简单使用可以看作者上篇博客(Ribbon默认负载均衡方式为轮询方式)
点这里->SpringCloud-Eureak服务注册中心

3.替换负载均衡方式
1)创建配置类
官方文档明确给出了警告:
这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。

在这里插入图片描述

@Configuration
public class MySelfRule {
    @Bean
    public IRule myRule()
    {
        return new RandomRule();//定义为随机
    }
}

2)在启动类上添加注解@RibbonClient,我这里用的是随机方式实现负载均衡

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration= MySelfRule.class)
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

三、Ribbon负载均衡算法

1.介绍
负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。

List instances = discoveryClient.getInstances(“CLOUD-PAYMENT-SERVICE”);

如:List [0] instances = 127.0.0.1:8002
  List [1] instances = 127.0.0.1:8001

8001+ 8002 组合成为集群,它们共计2台机器,集群总数为2, 按照轮询算法原理:

当总请求数为1时: 1 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001
当总请求数位2时: 2 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002
当总请求数位3时: 3 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001
当总请求数位4时: 4 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002
如此类推…

在这里插入代码片

2.手动模仿负载均衡
1)创建接口和类
在这里插入图片描述
LoadBanlancer接口

public interface LoadBalancer {
    ServiceInstance instances(List<ServiceInstance> serviceInstances);
}

实现类 MyLB,这里使用了自旋锁 CAS实现原子性操作;compareAndSet方法会判断cuurent和this.atomicInteger.get()是否相同,相同则将this.atomicInteger.get()更新为next,并且退出循环:
具体自旋锁可以看这篇博客:自旋锁
将返回的next与服务总数取余,余数为当前调用的服务下标,返回该服务信息ServiceInstance

@Component
public class MyLB implements LoadBalancer{
    private AtomicInteger atomicInteger = new AtomicInteger(0);
    public final int getAndIncrement(){
        int current;
        int next;
        do{
            current = this.atomicInteger.get();
            System.out.println(".... "+current);
            next = current>= Integer.MAX_VALUE? 0: current+1;
        }while(!this.atomicInteger.compareAndSet(current,next));
        System.out.println("第几次访问,次数next:"+next);
        return next;
    }
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}

80端口Controller添加如下代码
获得到服务信息,并且利用restTemplate调用对应的服务实现负载均衡

@Resource
private LoadBalancer loadBalancer;
@Resource
private DiscoveryClient discoveryClient;

@GetMapping("/consumer/payment/lb")
    public String getPaymentLB(){
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if(instances==null || instances.size()<=0){
            return null;
        }
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }

8001,8002端口Controller下添加如下代码

@GetMapping(value = "/payment/lb")
    public String getPaymentLB()
    {
        return serverPort;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值