Ribbon 负载均衡服务调用

news2024/11/25 21:39:20

文章目录

      • 1 SpringCloud Load Balance
      • 2 总结:
      • 3 Ribbon工作流程:
      • 4 自定义Ribbon 负载均衡算法:
        • 4.1 iRule接口:
        • 4.2 Ribbon自带的负载均衡算法:
        • 4.3 负载均衡算法替代:
          • 4.3.1、在非启动类包及子包下创建配置类
          • 4.3.2、定义
          • 4.3.3、启动类增加RibbonClient注解
      • 5 Ribbon负载均衡算法
        • 5.1 轮询算法原理:
        • 5.2 轮询算法源码:
        • 5.3 手写负载均衡算法

想要学习完整SpringCloud架构可跳转: SpringCloud Alibaba微服务分布式架构

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

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。

Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。

在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。

我们很容易使用Ribbon实现自定义的负载均衡算法。

1 SpringCloud Load Balance

LB负载均衡(Load Balance)是什么?

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

集中式LB Load Balance

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,1如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;

Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端实现的。

Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

2 总结:

Ribbon其实就是一个软负载均衡的客户端组件,

他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

在这里插入图片描述

3 Ribbon工作流程:

Ribbon在工作时分成两步:

  • 第—步先选择EurekaServer ,它优先选择在同一个区域内负载较少的server.
  • 第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。
  • 其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

4 自定义Ribbon 负载均衡算法:

4.1 iRule接口:

在这里插入图片描述

4.2 Ribbon自带的负载均衡算法:

com.netflix.loadbalancer.RoundRobinRule:

轮询

com.netflix.loadbalancer.RandomRule:

随机
com.netflix.loadbalancer.RetryRule:

先按照RoundRobinRule的策骼获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务

weightedResponseTimeRule:

对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择

BestAvailableRuleo:

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发是最小的服务

vailabilityFilteringRule:

先过滤掉故障实例,再选择并发较小的实例:

zoneAvoidanceRule

默认规则,复合判断server所在区域的性能和server的可用性选择服务器

官方文档明确给出了警告:

这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,
否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。

4.3 负载均衡算法替代:

4.3.1、在非启动类包及子包下创建配置类

在这里插入图片描述

4.3.2、定义
/**
 * Myrule : Ribbon 自定义负载均衡算法配置类
 *
 * @author zyw
 * @create 2023/6/18
 */
@Configuration
public class Myrule {

    @Bean
    public IRule getIRule(){
        //定义为随机
        return new RandomRule();
    }
}
4.3.3、启动类增加RibbonClient注解

自定义需要指定的服务

/**
 * OderMain80 :
 *
 * @author zyw
 * @create 2023/6/16
 */
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOULD-PAYMENT-SERVICE",configuration = Myrule.class)
@MapperScan("com.zyw.springcloud.dao")
public class OderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OderMain80.class,args);
    }
}

5 Ribbon负载均衡算法

5.1 轮询算法原理:

在这里插入图片描述

5.2 轮询算法源码:

public class RoundRobinRule extends AbstractLoadBalancerRule {
    
private AtomicInteger nextServerCyclicCounter;
    
public RoundRobinRule() {
   nextServerCyclicCounter = new AtomicInteger(0);
}


public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }

        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            //获取有正常运行的(可达的)服务集合
            List<Server> reachableServers = lb.getReachableServers();
            //获取可负载服务集合
            List<Server> allServers = lb.getAllServers();
            //获取有正常运行的(可达的)服务的数量
            int upCount = reachableServers.size();
             //获取可负载服务的数量 == 服务器集群总数量
            int serverCount = allServers.size();

            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }

            int nextServerIndex = incrementAndGetModulo(serverCount);
            server = allServers.get(nextServerIndex);

            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;
    }

    //自旋锁
    //rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启后rest接口计数从1开始。
        private int incrementAndGetModulo(int modulo) {
        for (;;) {
            //获取当前值
            int current = nextServerCyclicCounter.get();
            //计算下次值
            int next = (current + 1) % modulo;
            //比较并交换
            if (nextServerCyclicCounter.compareAndSet(current, next))
                //得到当前下标值
                return next;
        }
    }
    
}

5.3 手写负载均衡算法

/**
 * LoadBalancer : 自定义负载均衡算法
 *
 * @author zyw
 * @create 2023/6/20
 */
public interface LoadBalancer {

    //收集Eurek上所有活着的服务总数
    ServiceInstance instances(List<ServiceInstance> serviceInstances);

}
/**
 * MyLB : 自定义负载均衡算法实现类
 *
 * @author zyw
 * @create 2023/6/20
 */
@Component
public class MyLB implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement() {
        int currrnt;
        int next;
        do {
            currrnt = this.atomicInteger.get();
            //Integer.MAX_VALUE = 2147483647
            next = currrnt >= 2147483647 ? 0 : currrnt + 1;
            //自选锁,直到得到期望值
        } while (!this.atomicInteger.compareAndSet(currrnt, next));
        System.out.println("第" + next + "次访问");
        return next;
    }

    /**
     * rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启后rest接口计数从1开始。
     * @param serviceInstances
     * @return
     */
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}

/**
 * OrderController : 订单系统控制层
 *
 * @author zyw
 * @create 2023/6/16
 */
@Slf4j
@RestController
@RequestMapping("consumer/orderController")
@Api(tags={"订单系统控制层"})
public class OrderController {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private LoadBalancer loadBalancer;

    @GetMapping("/lb")
    @ApiOperation(value = "获取负载服务的端口号", response = String.class)
    public String getPaymentBl(){
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("CLOULD-PAYMENT-SERVICE");
        if (serviceInstances == null || serviceInstances.size() <= 0){
            return null;
        }

        ServiceInstance serviceInstance = loadBalancer.instances(serviceInstances);

        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"paymentController/lb",String.class);
    }


}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/746676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LayUI动态选项卡的使用

目录 一、Tab选项卡 1.什么是Tab选项卡 2.Tab选项卡的作用 二、Tab选项卡的详细使用步骤 1.参考官网&#xff0c;选择自己喜欢的选项卡 ​ 2.将静态选项卡转换成动态选项卡 3.将选项卡的标签名变成实际菜单名 4.重名选项卡不能二次打开 5.切换到指定选项卡 6.iframe的…

Python示例解释观察者模式

观察者模式是一种常用的设计模式&#xff0c;用于在对象之间建立一种一对多的依赖关系&#xff0c;当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。下面通过一个简单的例子来解释观察者模式的概念。 假设我们有一个名为"主题"&a…

神经网络万能近似定理探索与实验

神经网络万能近似定理探索与实验 今天&#xff0c;我们来做神经网络万能近似定理的探索与实验。关于万能近似定理呢&#xff0c;就是说&#xff0c;对这个神经元的输出进行非线性激活函数处理&#xff0c;单层的神经网络就可以拟合任何一个函数。 下面先看我们搭建的第一个网…

docker部署达梦数据库

一、下载安装包 安装步骤&#xff1a; 先跟着网页走 注&#xff1a;第二步导入安装包&#xff0c;如果是在自己电脑上&#xff0c;就不一定要拷贝到/opt目录下&#xff0c;在安装包所在目录地址栏输入cmd&#xff0c;进入终端进行操作即可 操作到正常打印日志&#xff08;如…

java项目之房屋租赁系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的房屋租赁系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&…

尚硅谷Docker实战教程-笔记14【高级篇,Docker容器监控之CAdvisor+InfluxDB+Granfana、Docker终章总结】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

centos7.9 连续登录失败处理

如果有人恶意破解你的服务器&#xff0c;下面的操作可以起到一定的作用&#xff0c;连续登录失败锁定账户一段时间&#xff0c;让攻击者的成本增加&#xff0c;从而降低服务器被恶意破解的风险。 参考博客 https://blog.csdn.net/hjxloveqsx/article/details/129004832 https…

MyBatis 中如何使用分页

MyBatis 中如何使用分页 在实际的项目开发中&#xff0c;我们经常需要对数据库中的数据进行分页查询&#xff0c;以提高数据查询的效率和用户体验。MyBatis 是一种流行的 Java 持久层框架&#xff0c;它提供了多种分页查询的方式&#xff0c;本文将介绍其中常用的两种方式&…

MySQL数据库详解

文章目录 引言1. SQL1.1 SQL通用语法1.2 SQL分类1.3 DDL1.3.1 数据库操作1.3.2 表操作1.3.2.1 表操作-查询创建1.3.2.2 表操作-数据类型1.3.2.3 表操作-修改1.3.2.3 表操作-删除 1.4 DML1.4.1 添加数据1.4.2 修改数据1.4.3 删除数据 1.5 DQL1.5.1 基本语法1.5.2 基础查询1.5.3 …

车载以太网之SOME/IP-SD专题篇

前言 首先,请问大家几个小小问题,你清楚: 你知道什么是SOME/IP SD吗?SOME/IP-SD报文是如何发送与接收的呢?SOME/IP-SD 存在哪几种Entry Type呢?SOME/IP-SD内部状态机转换又是如何?今天,我们就来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲: 目录…

Sentinel 规则详解

Sentinel 规则 流控规则 flow1、QPS流控2、并发线程数流控3、流控模式4、流控效果 熔断&#xff08;降级&#xff09;规则 degrade1、慢调用比例2、异常比例3、异常数 热点规则 param-flow授权规则 authority1、应用场景2、自定义来源3、授权规则配置 系统规则 前言&#xff1a…

代码随想录day1 | 704.二分查找 27.移除元素

一、二分 1、二分易错点 1、循环变量 while(left < right) 还是while(left <right)2、判断条件 if(num[mid] > tar) mid right 还是 mid right -12、循环不变量 [left, right] [left, right) (left, right]3、左闭右闭写法 当时左闭右闭时&#xff0c;while循…

2、基于kubeadm搭建K8S环境

目录 一、环境说明 二、初始化所有节点 三、修改三台服务器主机名&#xff0c;并写入host文件 四、调整内核参数 五、所有节点安装Docker 六、所有节点配置K8S源 七、所有节点安装kubeadm&#xff0c;kubelet和kubectl 八、部署 kubernetes Master 节点 九、k8s-node …

基于docker的keepalived+MySQL主从实现MySQL高可用

因生产需要对MySQL做高可用&#xff0c;同时&#xff0c;资源有限&#xff0c;因此采用双节点主从keepalived方式实现高勇。另外因需要大批量部署MySQL集群&#xff0c;需要采用模板化部署&#xff0c;本方案采用将MySQL容器化&#xff0c;实现MySQL模板化配置部署。 部署环境及…

SpringMVC学习笔记--上篇

SpringMVC学习笔记 1、SpringMVC 1.1、什么是SpringMVC Spring MVC是Spring Framework的一部分&#xff0c;是基于Java实现MVC的轻量级Web框架。 1.2、SpringMVC的特点 Spring MVC的特点&#xff1a; 轻量级&#xff0c;简单易学高效 , 基于请求响应的MVC框架与Spring兼容…

Python深度学习-有向图合并、排序、最长路径计算

一、有向图方向、权重表示方法 Python通常使用有向图中边的起点和终点来表示边的方向。例如&#xff0c;如果有一条从节点A到节点B的边&#xff0c;则可以使用以下方式表示该有向边&#xff1a; graph {A: {B: 1} }在这个例子中&#xff0c;节点A和节点B之间存在一条权重为1…

谷歌插件下载Redux DevTools管理Redux数据

我们在做 react-redux开发时 很多时候可能无法确定自己的数据有没有成功导进来 这里就有个不错的谷歌插件推荐给大家 大家可以下载我的资源 谷歌插件Redux DevTools 这里 我们打开 Google Chrome浏览器 然后 直接在谷歌浏览器上访问 chrome://extensions/ 如果你的第一次进入 …

【网络安全】学过编程就是黑客?

我们不可否认的是黑客为我们带来了巨大的财产损失于危机&#xff0c;即使其最初的思想是正确的。 个人主页&#xff1a;【&#x1f60a;许思王】 文章目录 前言黑客 &#x1f4bb;起源&#x1f697;发展&#x1f463;黑客守则&#xff08;真的假的&#x1f914;&#xff09;黑…

合并cyclonedx格式的bom文件

1.工具下载 https://github.com/CycloneDX/cyclonedx-cli/releases 2.操作记录 Usage: cyclonedx [options] [command] Options: --version Show version information -?, -h, --help Show help and usage information Commands: add Add information to a BOM (currently…