服务负载均衡Ribbon

news2024/12/23 22:22:25

服务负载均衡Ribbon

  • Ribbon 介绍
  • Ribbon 案例
  • Ribbon 负载均衡策略
  • Ribbon 负载均衡算法设置
  • 自定义负载均衡算法

Ribbon 介绍

Ribbon 是一个的客服端负载均衡工具,它是基于 Netflix Ribbon 实现的。它不像 Spring Cloud 服务注册中心、配置中心、API 网关那样独立部署,但是它几乎存在于每个 Spring Cloud 微服务中。它内部提供了一个叫做ILoadBalance的接口代表负载均衡器的操作,比如有添加服务器操作、选择服务器操作、获取所有的服务器列表、获取可用的服务器列表等。

客户端的负载均衡:在客户端发起远程调用的时候进行负载均衡,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这就是客户端负载均衡;即在客户端就进行负载均衡算法分配。Ribbon就是一个客户端的负载均衡工具。

服务端的负载均衡:客户端发起远程调用到服务器,服务器根据服务列表,使用负载均衡算法,选择一个远程服务进行调用。nginx 就可以实现服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的,需要在nginx配置所有的服务提供者信息。

Ribbon 负载均衡流程
请添加图片描述
客户端发起请求,请求会被Ribbon拦截,Ribbon会去注册中心,读取请求的服务列表,会将获取注册信息服务列表之后缓存到本地,根据返回的服务列表,进行负载均衡,选择一个服务去进行调用。

Ribbon 案例

在服务消费者,添加 Ribbon 依赖,如果已经引入了 spring-cloud-starter-netflix-eureka-client 依赖,就不需要添加Ribbon的依赖了,在eureka-client已经添加了Ribbon的依赖。

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

微服务之间的通信方式,常见的方式有两种:RPC(dubbo),HTTP(SpringCloud)
在SpringCloud中,默认是使用 http 来进行微服务的通信,最常用的实现形式有两种:RestTemplate和OpenFeign。这里使用RestTemplate进行远程调用。
RestTemplate 需要手动创建 RestTemplate bean,并且使用该bean进行http请求。
在使用 RestTemplate 进行 Eureka Client 之间的通信,为 RestTemplate 配置类添加@LoadBalanced注解即可开启Ribbon的负载均衡,

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
	return new RestTemplate();
}

服务提供者配置,需要向注册中心,注册多个相同的服务,使用Ribbon进行负载均衡,进行选择。
服务提供者1配置
添加依赖

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

配置文件

server:
  port: 8001
spring:
  application:
    #该名称在集群模式下应该保持一致
    name: provider
eureka:
  client:
    #设置服务注册中心地址
    service-url:
      defaultZone: http://localhost:1000/eureka/  #定义服务中心的地址

服务提供者2配置
添加依赖

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

配置文件

server:
  port: 8002
spring:
  application:
    #该名称在集群模式下应该保持一致
    name: provider
eureka:
  client:
    #设置服务注册中心地址
    service-url:
      defaultZone: http://localhost:1000/eureka/  #定义服务中心的地址

服务提供者1和服务提供者2,服务名称必须相同。不同会当作两个不同的服务。

服务消费者进行调用,在调用的时候,使用服务提供者的服务名称,会根据名称到 Eureka 中获取服务列表,当有多个相同的服务时,使用Ribbon做负载均衡,选择其中一个进行调用。

@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
	// 1.查询订单
    Order order = orderMapper.findById(orderId);
    // 2.利用RestTemplate发起http请求,查询用户
    // 2.1.url路径
    String url = "http://provider/user/" + order.getUserId();
    // 2.2.发送http请求,实现远程调用
    User user = restTemplate.getForObject(url, User.class);
    // 3.封装user到Order
    order.setUser(user);
    // 4.返回
    return order;
}

Ribbon 负载均衡策略

在这里插入图片描述
RoundRobinRule:默认使用,简单轮询。
WeightedResponseTimeRule:设置权重,权重越大,越容易被访问,越小,越不容易被访问。
RandomRule:随机选择一个可用的服务。
RetryRule:轮询的增强版,轮询策略服务不可用时不做处理,重试策略服务不可用时会重新尝试集群中的其他节点。
BestAvailableRule:选择正在请求中的并发数最小的服务,除非这个服务在熔断中。
AvailabilityFilteringRule:忽略高并发和短路。过滤掉并发数高的,过滤掉连接失败的。
ZoneAvoidanceRule:以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的 provider。如果这个 ip 区域内有一个或多个实例不可达或响应变慢,都会降低该 ip 区域内其他 ip 被选中的权重。

Ribbon 负载均衡算法设置

全局替换,在启动类或配置类注入策略类对象,在所有的服务请求中均使用该策略。
注入随机策略类,在所有的服务进行远程调用的时候,将会采用随机的负载均衡策略。

@Bean
public IRule randomRule() {
	return new RandomRule();
}

局部替换,为每一个服务定义不同的负载均衡策略。修改配置文件。
对 userservice 服务设置负载均衡策略。

# 负载均衡策略
# userservice 为调用的服务的名称
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule# 负载均衡规则 

自定义负载均衡算法

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则。
在这里插入图片描述
想要实现自定义负载均衡规则,只需要编写一个类继承AbstractLoadBalancerRule。

IRule 接口
在这里插入图片描述
AbstractLoadBalancerRule对setLoadBalaner 方法和getLoadBalancer 方法进行了实现。把获取到的值进行赋值保存,方便的子类的使用,这两个方法可以看作是获取服务中心的服务信息。
在这里插入图片描述
自定义负载均衡算法需要继承IRule的抽象实现类AbstractLoadBalancerRule,可以写一个类去实现它,然后在 Server choose(Object key) 里面设置规则。
自定义一个轮询的策略类。

public class MyRoundRobinRule extends AbstractLoadBalancerRule {
    //定义一个原子类,以保证原子性
    private AtomicInteger atomicInteger = new AtomicInteger(0);
    
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
	// lb 服务列表
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null){
            return null;
        }
        //用于统计获取次数,当达到一定数量就不再去尝试
        int count = 0;
        Server server = null;
        //当服务还没获取到,并且尝试没有超过8次
        while (server == null && count++ < 8){
            //获取服务
            List<Server> allServers = lb.getAllServers();
            List<Server> reachableServers = lb.getReachableServers();
            int allServersSize = allServers.size();
            int reachableServersSize = reachableServers.size();
            //如果获取的服务list都为0就返回null
            if(allServersSize == 0 || reachableServersSize == 0){
                return  null;
            }
            //获取服务下标
            int next = getServerIndex(allServersSize);
            //获取服务
            server = reachableServers.get(next);
            //如果服务为空直接跳过下面的
            if (server == null){
                continue;
            }
            //如果获取到的这个服务是活着的就返回
            if (server.isAlive()){
                return server;
            }
            //如果获取到的服务不是空,但是不是存活状态,需要重新获取
            server = null;
        }
        //最后这里可能会返回null
        return  server;
    }
    //获取服务下标,为了保证原子性,使用了CAS
    public int getServerIndex(int allServersSize){
        //自旋锁
        for (;;) {
            //获取当前值
            int current = this.atomicInteger.get();
            //设置期望值
            int next = (current + 1) % allServersSize;
            //调用Native方法compareAndSet,执行CAS操作
            if (this.atomicInteger.compareAndSet(current, next))
                //成功后才会返回期望值,否则无线循环
                return next;
        }
    }
    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(),key);
    }
}

在配置类中注入写好的自定义策略类,注意,使用这种方式为全局替换。

@Bean
public IRule randomRule() {
	return new MyRoundRobinRule();
}

也可以使用局部替换,在配置文件中进行设置。

# 负载均衡策略
# userservice 为调用的服务的名称
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.springcloud.rule.MyRoundRobinRule #负载均衡规则 

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

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

相关文章

使用Postman创建Mock Server

这篇文章将教会大家如何利用 Postman&#xff0c;通过 Mock 的方式测试我们的 API。 什么是 Mock Mock 是一项特殊的测试技巧&#xff0c;可以在没有依赖项的情况下进行单元测试。通常情况下&#xff0c;Mock 与其他方法的主要区别就是&#xff0c;用于取代代码依赖项的模拟对…

论文笔记 | 谷歌 Soft Prompt Learning ,Prefix-Tuning的 -> soft promt -> p tuning v2

论文笔记 | 谷歌 Soft Prompt Learning ptuning -> Prefix-Tuning -> soft promt -> p tuning v2 "The Power of Scale for Parameter-Efficient Prompt Tuning" EMNLP 2021 Google Brain 人能理解的不一定是模型需要的&#xff0c;所以不如让模型自己训…

多线程之线程安全

写在前面 本文一起看下线程安全相关内容。 1&#xff1a;重要的概念 1.1&#xff1a;竞态条件 多个线程竞争同一资源&#xff0c;如果是对多个线程访问资源的顺序敏感&#xff08;即导致非预期结果&#xff09;&#xff0c;则该资源就是竞态条件。 1.2&#xff1a;临界区 …

亚毫秒GC暂停到底有多香?JDK17+ZGC初体验|得物技术

1 前言 垃圾回收器的暂停问题一直是Java工程师关注的重点&#xff0c;特别是对实时响应要求较高的服务来说&#xff0c;CMS和G1等主流垃圾回收器的数十毫秒乃至上百毫秒的暂停时间相当致命。此外&#xff0c;调优门槛也相对较高&#xff0c;需要对垃圾回收器的内部机制有一定的…

Nodejs六、数据库操作

零、文章目录 Nodejs六、数据库操作 1、MYSQL数据库 MYSQL相关知识请参考MYSQL基础 2、在项目中操作 MySQL &#xff08;1&#xff09;操作数据库的步骤 安装操作 MySQL 数据库的第三方模块&#xff08;mysql&#xff09;通过 mysql 模块连接到 MySQL 数据库通过 mysql 模…

chatgpt赋能python:Python编写网站的SEO指南

Python 编写网站的 SEO 指南 Python 是一个高可扩展性和灵活性的编程语言&#xff0c;在创建面向 Web 的应用程序和网站时非常强大。但是&#xff0c;即使你创建了一个出色的网站&#xff0c;也需要将它放在正确的地方以便被人们发现。 搜索引擎优化&#xff08;SEO&#xff0…

【深度学习】2-2 神经网络 - 前向传播实现3层神经网络

神经网络分层 神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。 用图来表示神经网络的话&#xff0c;把最左边的一列称为输入层&#xff0c;最右边的一列称为输出层&#xff0c;中间的一列称为中间层。中间层有时也叫隐藏层&#xff08;或隐含层&#xf…

深入了解计算机SNMP协议:原理、功能和应用场景

前言 简单网络管理协议&#xff08;SNMP&#xff09;是一种用于管理网络设备的协议&#xff0c;它可以让管理员通过网络对设备进行监控、配置和故障排除等操作。本文将详细介绍SNMP的版本、管理信息库MIB、管理信息结构&#xff08;SMI&#xff09;、SNMP报文、5种协议数据单元…

avive零头撸矿

Avive 是一个透明的、自下而上替代自上而下的多元网络&#xff0c;旨在克服当前生态系统的局限性&#xff0c;实现去中心化社会。 aVive&#xff1a;一个基于 SBT 和市场的 deSoc&#xff0c;它使 dapps 能够与分散的位置 oracle 和 SBT 关系进行互操作。您的主权社交网络元宇宙…

Vue中如何进行表单验证码与滑动验证?

Vue中如何进行表单验证码与滑动验证&#xff1f; 在Web应用程序中&#xff0c;表单验证码和滑动验证是常见的安全机制&#xff0c;用于防止恶意攻击和机器人攻击。在Vue中&#xff0c;我们可以使用许多不同的库来实现这些功能。本文将介绍如何使用Vue和vue-verify-code库来实现…

docker中部署lnmp架构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 docker中部署lnmp架构 前言一、安装docker和docker-compose二、文件部署准备三、创建ngixn虚拟主机配置文件四、创建html文件夹五、启动容器文件结构 前言 Docker是一种轻量…

5.6.1 Ext JS之标签页的关闭和批量关闭

Tab Panel 是包含多个标签页的面板, 这是一种很常用的组件, 类似于浏览器的标签页。关于 Ext JS的Tab Panel的基本使用可以参考: [Ext JS3.9] 标签面板(TabPanel )介绍与开发, 本篇介绍如何关闭单个标签页和批量关闭标签页。 Tab 标签页的可关闭 默认状况下,标签页是无…

23.反射(reflection)|Java学习笔记

文章目录 反射机制Java反射机制原理图Java反射机制可以完成反射相关的主要类反射优点和缺点 Class类 反射机制 一个简单的例子&#xff1a; package com.edu.reflection.question;import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Invo…

消防安全知识答题活动小程序v5.0-支持答题后抽奖

关于答题抽奖活动小程序的设计思考 1. 功能设计&#xff1a;作为答题抽奖活动小程序&#xff0c;核心功能应包括答题和抽奖两部分。用户通过答题获取抽奖机会&#xff0c;答题可以设置为多个题目&#xff0c;用户回答正确则获得相应分数。在用户答完问题后&#xff0c;可以立即…

优思学院|企业业绩差的7大原因,善用精益管理可解决

在当今竞争激烈的商业环境中&#xff0c;一些企业的业绩表现出了较差的趋势&#xff0c;这可能是由于多种原因造成的。下面将探讨企业业绩差的七大原因&#xff0c;并介绍如何善用精益管理来提升企业的绩效。 1. 战略定位不清 企业业绩差的一个常见原因是战略定位不清。如果企…

如何用流量涡轮打造属于自己的汽车行业高价值私域流量池

01. 私域提升品牌价值 2010年以来&#xff0c;中国汽车工业就一直处于两位数的增长。这使得国内外品牌都能在市场上站稳脚跟。这为许多汽车公司提供了获得可观利润的绝佳机会。汽车成为明星行业&#xff0c;在此阶段的车企高管们也成为了行业翘楚。然而&#xff0c;2018年之后…

延迟渲染G-buffer所占显存带宽计算(解决移动端和抗锯齿的若干疑问)

延迟渲染需要在前面阶段&#xff0c;将计算的内容保留在N张G-buffer中&#xff0c;但是网上的文章只是提及了G-buffer应该压缩&#xff0c;并且尽量少用&#xff0c;没有说明G-buffer所占带宽应该是多少&#xff0c;我将在下面介绍G-buffer所占显存带宽的详细计算方法 G-buffe…

4、DuiLib了解 XML使用和布局控制

文章目录 1、了解 XML使用和布局控制2、内外边距3、浮动4、占位符5、默认样式6、全局字体 1、了解 XML使用和布局控制 通过上一篇的学习我们可以制作一个简单的布局了&#xff0c;但是没有控件的窗口做再好的布局有什么用呀。赶紧找些素材&#xff0c;我们来做一个标准的 Wind…

黄金期货交易规则有哪些?黄金期货交易规则详解

黄金期货交易是一种高风险的投资工具&#xff0c;因此新手投资者在准备交易前建议先学习重要的黄金期货交易规则&#xff0c;对黄金期货产品交易有一个大概的了解。黄金期货交易规则有哪些&#xff1f;以下是重要的黄金期货交易规则详解 黄金期货交易规则一、交易前需要先开户 …

在Deepin虚机中共享使用主机文件夹

一、系统环境&#xff1a; 操作系统&#xff1a;Win11 虚机版本&#xff1a;VMWare workstation 16 pro 虚机系统&#xff1a;deepin 20.9 二、主机中操作 VMWare Workstation/虚拟机/设置/选项/共享文件夹 默认为已禁用&#xff0c;在右侧选择“总是启用”&#xff0c;在…