Spring Cloud之负载均衡与服务调用(Ribbon)

news2024/11/15 10:52:40

目录

Ribbon

简介

负载均衡

简介

负载均衡方式

服务端负载均衡

工作原理

特点

客户端负载均衡

工作原理

特点

对比

实现

负载均衡策略

切换负载均衡策略

定制负载均衡策略

超时与重试

单个服务配置

全局配置

服务调用

示例


Ribbon

简介

        Ribbon 是 Netflix 公司发布的开源组件,其主要功能是提供客户端的负载均衡算法和服务调用;通过它,我们可以将面向服务的 REST 模板请求转换为客户端负载均衡的服务调用。微服务之间的调用,API 网关的请求转发等内容,实际上都是通过 Ribbon 来实现的。

负载均衡

简介

        在任何一个系统中,负载均衡都是一个十分重要且不得不去实施的内容,它是系统处理高并发、缓解网络压力和服务端扩容的重要手段之一。

        负载均衡,简单点说就是将用户的请求平摊分配到多个服务器上运行,以达到扩展服务器带宽、增强数据处理能力、增加吞吐量、提高网络的可用性和灵活性的目的。

负载均衡方式

常见的负载均衡方式有两种:服务端负载均衡、客户端负载均衡

服务端负载均衡
工作原理

        服务端负载均衡是在客户端和服务端之间建立一个独立的负载均衡服务器,该服务器既可以是硬件设备(例如 F5),也可以是软件(例如 Nginx)。这个负载均衡服务器维护了一份可用服务端清单,然后通过心跳机制来删除故障的服务端节点,以保证清单中的所有服务节点都是可以正常访问的。

        当客户端发送请求时,该请求不会直接发送到服务端进行处理,而是全部交给负载均衡服务器,由负载均衡服务器按照某种算法(例如轮询、随机等),从其维护的可用服务清单中选择一个服务端,然后进行转发。

特点

        1.需要建立一个独立的负载均衡服务器

        2.负载均衡是在客户端发送请求后进行的,因此客户端并不知道到底是哪个服务端提供的服务

        3.可用服务端清单存储在负载均衡服务器上

客户端负载均衡

相较于服务端负载均衡,客户端服务在均衡则是一个比较小众的概念

工作原理

        客户端负载均衡是将负载均衡逻辑以代码的形式封装到客户端上,即负载均衡器位于客户端。客户端通过服务注册中心(例如 Eureka Server)获取到一份服务端提供的可用服务清单。有了服务清单后,负载均衡器会在客户端发送请求前通过负载均衡算法选择一个服务端实例再进行访问,以达到负载均衡的目的;

        客户端负载均衡也需要心跳机制去维护服务端清单的有效性,这个过程需要配合服务注册中心一起完成 

特点

        1.负载均衡器位于客户端,不需要单独搭建一个负载均衡服务器

        2.负载均衡是在客户端发送请求前进行的,因此客户端清楚地知道是哪个服务端提供的服务

        3.客户端都维护了一份可用服务清单,而这份清单都是从服务注册中心获取的

        Ribbon 就是一个基于 HTTP 和 TCP 的客户端负载均衡器,当我们将 Ribbon 和 Eureka 一起使用时,Ribbon 会从 Eureka Server(服务注册中心)中获取服务端列表,然后通过负载均衡策略将请求分摊给多个服务提供者,从而达到负载均衡的目的

对比

实现

        Ribbon 是一个客户端的负载均衡器,它可以与 Eureka 配合使用轻松地实现客户端的负载均衡。Ribbon 会先从 Eureka Server(服务注册中心)去获取服务端列表,然后通过负载均衡策略将请求分摊给多个服务端,从而达到负载均衡的目的

负载均衡策略
序号实现类负载均衡策略
1RoundRobinRule轮询策略,即按照一定的顺序依次选取服务实例
2RandomRule随机选取一个服务实例
3RetryRule按照轮询的策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试,如果超过指定时间依然没获取到服务实例则返回 null 
4WeightedResponseTimeRule根据平均响应时间,来计算所有服务实例的权重,响应时间越短的服务实例权重越高,被选中的概率越大
5BestAvailableRule先过滤点故障或失效的服务实例,然后再选择并发量最小的服务实例
6AvailabilityFilteringRule先过滤掉故障或失效的服务实例,然后再选择并发量较小的服务实例
7ZoneAvoidanceRule默认的负载均衡策略,综合判断服务所在区域的性能和服务的可用性,来选择服务实例
切换负载均衡策略

Ribbon 默认使用轮询策略选取服务实例,我们也可以根据自身的需求切换负载均衡策略,只需要在服务消费者(客户端)的配置类中,将 IRule 的其他实现类注入到容器中即可

在配置类 ConfigBean 中添加以下代码,将负载均衡策略切换为 RandomRule(随机)

@Bean
public IRule myRule() {
    // RandomRule 为随机策略
    return  new RandomRule();
}
定制负载均衡策略

1.创建一个名为 MyRandomRule 的类

package net.biancheng.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;

/**
* 定制 Ribbon 负载均衡策略
*/
public class MyRandomRule extends AbstractLoadBalancerRule {
    private int total = 0;            // 总共被调用的次数,目前要求每台被调用5次
    private int currentIndex = 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();

            //如果没有任何的服务实例则返回 null
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }
            //与随机策略相似,但每个服务实例只有在调用 3 次之后,才会调用其他的服务实例
            if (total < 3) {
                server = upList.get(currentIndex);
                total++;
            } else {
                total = 0;
                currentIndex++;
                if (currentIndex >= upList.size()) {
                    currentIndex = 0;
                }
            }
            if (server == null) {
                Thread.yield();
                continue;
            }
            if (server.isAlive()) {
                return (server);
            }
            server = null;
            Thread.yield();
        }
        return server;
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        // TODO Auto-generated method stub
    }
}

2.创建一个名为 MySelfRibbonRuleConfig 的配置类,将我们定制的负载均衡策略实现类注入到容器中

/**
* 定制 Ribbon 负载均衡策略的配置类
* 该自定义 Ribbon 负载均衡策略配置类 不能在 net.biancheng.c 包及其子包下
* 否则所有的 Ribbon 客户端都会采用该策略,无法达到特殊化定制的目的
*/
@Configuration
public class MySelfRibbonRuleConfig {
    @Bean
    public IRule myRule() {
        //自定义 Ribbon 负载均衡策略
        return new MyRandomRule(); //自定义,随机选择某一个微服务,执行五次
    }
}

3.修改位于启动类,在该类上使用 @RibbonClient 注解让我们定制的负载均衡策略生效

@SpringBootApplication
@EnableEurekaClient
//自定义 Ribbon 负载均衡策略在主启动类上使用 RibbonClient 注解,在该微服务启动时,就能自动去加载我们自定义的 Ribbon 配置类,从而是配置生效
// name 为需要定制负载均衡策略的微服务名称(application name)
// configuration 为定制的负载均衡策略的配置类,
// 且官方文档中明确提出,该配置类不能在 ComponentScan 注解(SpringBootApplication 注解中包含了该注解)下的包或其子包中,即自定义负载均衡配置类不能在 net.biancheng.c 包及其子包下
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT", configuration = MySelfRibbonRuleConfig.class)
public class MicroServiceCloudConsumerDept80Application {
    public static void main(String[] args) {
        SpringApplication.run(MicroServiceCloudConsumerDept80Application.class, args);
    }
}

超时与重试

        使用HTTP发起请求难免会发生问题,在F版开始Ribbon的重试机制默认是开启的,需要添加对超时时间与重试策略的配置;

单个服务配置
RIBBON-SERVICE-B:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    ConnectTimeout: 3000
    ReadTimeout: 60000
    MaxAutoRetries: 3 #对第一次请求的服务的重试次数
    MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
    OkToRetryOnAllOperations: true
全局配置
ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000
  MaxAutoRetries: 3 #对第一次请求的服务的重试次数
  MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
  OkToRetryOnAllOperations: true

服务调用

        Ribbon 可以与 RestTemplate(Rest 模板)配合使用,以实现微服务之间的调用

        RestTemplate 是 Spring 家族中的一个用于消费第三方 REST 服务的请求框架。RestTemplate 实现了对 HTTP 请求的封装,提供了一套模板化的服务调用方法。通过它,Spring 应用可以很方便地对各种类型的 HTTP 请求进行访问。

示例

1.引入依赖

        <!--Spring Cloud Ribbon 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

2.创建请求,调用服务端提供的服务

@RestController
public class DeptController_Consumer {
    //private static final String REST_URL_PROVIDER_PREFIX = "http://localhost:8001/"; 这种方式是直调用服务方的方法,根本没有用到 Spring Cloud

    //面向微服务编程,即通过微服务的名称来获取调用地址
    private static final String REST_URL_PROVIDER_PREFIX = "http://MICROSERVICECLOUDPROVIDERDEPT"; // 使用注册到 Spring Cloud Eureka 服务注册中心中的服务,即 application.name

    @Autowired
    private RestTemplate restTemplate; //RestTemplate 是一种简单便捷的访问 restful 服务模板类,是 Spring 提供的用于访问 Rest 服务的客户端模板工具集,提供了多种便捷访问远程 HTTP 服务的方法

    //获取指定部门信息
    @RequestMapping(value = "/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Integer id) {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/get/" + id, Dept.class);
    }
    //获取部门列表
    @RequestMapping(value = "/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/list", List.class);
    }
}

3.访问

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

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

相关文章

【滴滴出行安全应急响应平台DSRC2倍积分卡】

1、使用方法 2、券&#xff08;记得点个关注&#xff0c;做一下数据&#xff09;

Node学习笔记之MongoDB

一、简介 1.1 Mongodb 是什么 MongoDB 是一个基于分布式文件存储的数据库&#xff0c;官方地址 MongoDB: The Developer Data Platform | MongoDB 1.2 为什么选择 Mongodb 操作语法与 JavaScript 类似&#xff0c;容易上手&#xff0c;学习成本低 二、核心概念 Mongodb 中…

Unity地面交互效果——1、局部UV采样和混合轨迹

大家好&#xff0c;我是阿赵。   这期开始&#xff0c;打算介绍一下地面交互的一些做法。 比如&#xff1a; Unity引擎制作沙地实时凹陷网格的脚印效果 或者&#xff1a; Unity引擎制作雪地效果 这些效果的实现&#xff0c;需要基于一些基础的知识。所以这一篇先介绍一下简单…

大模型(LLM)在电商推荐系统的探索与实践

本文对LLM推荐的结合范式进行了梳理和讨论&#xff0c;并尝试将LLM涌现的能力迁移应用在推荐系统之中&#xff0c;利用LLM的通用知识来辅助推荐&#xff0c;改善推荐效果和用户体验。 背景 电商推荐系统&#xff08;Recommend System&#xff0c;RecSys&#xff09;是一种基于…

C++-openssl-aes-加密解密

hmac Hash-based Message Authentication Code MAC 定义&#xff1a; Message Authentication Code 一种确认完整性并进行认证的技术。 1.openssl基本版 加密解密 #include "openssl/rand.h" #include "openssl/md5.h" #include "openssl/hmac.h…

5G技术在职业教育领域的应用:产生巨变的技术

5G技术在职业教育领域的应用&#xff1a;产生巨变的技术 职业教育领域正面临着前所未有的挑战和机遇。随着5G技术的快速发展和普及&#xff0c;其高速度、低延迟、大容量和连接数的特性给职业教育带来了革命性的改变。本文将深入探讨5G技术在职业教育领域的应用场景、技术原理和…

Android Studio错误修复Connect to repo.maven.apache.org:443

环境 名称版本操作系统Windows10(64位)AndroidStudio2022.3.1 Patch 2 前言 最近更新了AndroidStudio编写程序的时候发现gradle时老是报read time out错误提示 分析 当出现这个警告时&#xff0c;你应该猜到这是一个连接不上的问题(Connect to repo.maven.apache.org:443)&…

huoshan device_id和iid生成记录学习分析

huoshan 和 douyin 作为字节系的产品&#xff0c;device_id 和 iid是抓包经常遇到的字段&#xff0c;代表了设备的概念。 还是熟悉的接口&#xff0c;像 device_register &#xff0c;app_alert_check 和 app_notice_status 都需要请求一遍。 这些接口跑完一遍&#xff0c;设…

【强烈推荐】视频转gif、图片拼gif,嘎嘎好用,免费免费真的免费,亲测有效,无效过来打我

问题描述 最近遇到一个需求是需要将视频生成gif&#xff0c;这个看上去不是很难&#xff0c;所以有了以下的解决办法 解决办法 首先想到的当然是自己写一个&#xff0c;用了两套代码&#xff1a; from moviepy.editor import *# 读取视频文件 video_clip VideoFileClip(&quo…

若依微服务上传图片文件代理配置

在使用若依微服务文件上传时候,文件上传成功会上传到D:/ruoyi/uploadPath目录下。默认使用9300端口进行访问图片文件,现在我想把它代理到80端口应该怎么做呢? 配置前:http://localhost:9300/statics/2023/09/24/test.jpg 配置后:http://localhost/statics/2023/09/24/test…

Kafka KRaft模式探索

1.概述 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer&#xff0c;以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 2.内容…

StableDiffusion学习

模型推荐 majicMIX realistic 麦橘写实(写实近景人像): https://civitai.com/models/43331/majicmix-realisticDreamShaper(各种画风, 比较全能): https://civitai.com/models/4384/dreamshaperLOFI (更精致人像面部): https://civitai.com/models/9052?modelVersionId146253…

MSQL系列(九) Mysql实战-Join算法底层原理

Mysql实战-Join算法底层原理 前面我们讲解了BTree的索引结构&#xff0c;及Mysql的存储引擎MyISAM和InnoDB,今天我们来详细讲解下Mysql的查询连接Join的算法原理 文章目录 Mysql实战-Join算法底层原理1.Simple Nested-Loop Join 简单嵌套循环2.Block Nested-Loop Join 块嵌套…

查找算法-二分查找法(Binary Search)

目录 查找算法-二分查找法&#xff08;Binary Search&#xff09; 1、说明 2、算法分析 3、C代码 查找算法-二分查找法&#xff08;Binary Search&#xff09; 1、说明 如果要查找的数据已经事先排好序了&#xff0c;就可以使用二分查找法来进行查找。二分查找法是将数据…

HackTheBox - Starting Point -- Tier 0 ---Preignition

文章目录 一 题目二 实验过程 一 题目 Tags Network、Programming、RDP、Reconnaissance、Weak Credentials译文&#xff1a;网络、编程、RDP、侦察、凭证薄弱Connect To attack the target machine, you must be on the same network.Connect to the Starting Point VPN us…

【面试经典150 | 链表】合并两个有序链表

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;递归方法二&#xff1a;迭代 写在最后 Tag 【递归】【迭代】【链表】 题目来源 21. 合并两个有序链表 题目解读 合并两个有序链表。 解题思路 一种朴素的想法是将两个链表中的值存入到数组中&#xff0c;然后对数组…

16、window11+visual studio 2022+cuda+ffmpeg进行拉流和解码(RTX3050)

基本思想:需要一个window11 下的gpu的编码和解码代码,逐开发使用,先上个图 几乎0延迟的,使用笔记本的显卡 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\extras\demo_suite>deviceQuery.exe deviceQuery.exe Starting...CUDA Device Query (Runtime API…

Xcode自定义快捷键

一、新建脚本 1. 编写脚本 把脚本sh文件保存在安全的目录&#xff0c;不会被删除 我这里主要是两个常用的&#xff1a; 1.打开终端: xcode-terminal.sh #!/bin/shif [ -n "$XcodeProjectPath" ]; then open -a Terminal "$XcodeProjectPath"/.. elseo…

macOS鼠标管理操作增强BetterMouse简体中文

BetterMouse是一款专为Mac用户设计的鼠标增强工具&#xff0c;旨在帮助用户更好地掌握和管理鼠标操作。它提供了全局鼠标手势、高度可定制的鼠标设置选项以及一些有用的鼠标增强功能&#xff0c;如鼠标放大镜、鼠标轨迹和应用程序切换功能。这些功能可以大大提高用户的工作效率…

Redis桌面管理工具:Redis Desktop Manager for Mac

Redis Desktop Manager是一款非常实用的Redis管理工具&#xff0c;它不仅提供了方便易用的图形用户界面&#xff0c;还支持多种Redis数据结构&#xff0c;可以帮助用户轻松地完成Redis数据库的管理工作。 以下是一些推荐Redis Desktop Manager的理由&#xff1a; 多平台支持&a…