如何使用 Spring Cloud 实现客户端负载平衡

微服务系统通常运行每个服务的多个实例。这是实施弹性所必需的。因此,在这些实例之间分配负载非常重要。执行此操作的组件是负载均衡器。Spring 提供了一个 Spring Cloud Load Balancer 库。在本文中,您将学习如何使用它在 Spring Boot 项目中实现客户端负载均衡。

客户端和服务器端负载均衡

当一个微服务调用另一个部署了多个实例的服务并在这些实例上分配负载而不依赖外部服务器来完成这项工作时,我们讨论了客户端负载均衡。相反,在服务器端模式下,平衡功能被委托给一个单独的服务器,该服务器分派传入的请求。在本文中,我们将讨论一个基于客户端场景的示例。

负载均衡算法

有几种方法可以实现负载平衡。我们在这里列出了一些可能的算法:

  • Round robin:以循环方式依次选择实例(在调用序列中的最后一个实例后,我们从第一个实例重新开始)。
  • Random choice:实例是随机选择的。
  • Weighted:根据某个数量(例如 CPU 或内存负载)分配给每个节点的权重进行选择。
  • Same instance:如果可用,则选择之前调用的相同实例。

Spring Cloud 为上述所有场景提供了易于配置的实现。

Spring Cloud Load Balancer 启动器

假设您使用 Maven,要将 Spring Cloud Load Balancer 集成到 Spring Boot 项目中,您应该首先在依赖项管理部分中定义发布队列:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>2023.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

然后,您应该在依赖项列表中包含 name:spring-cloud-starter-loadbalancer

XML 格式
<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  </dependency>        
  ...     
</dependencies>

负载均衡配置

我们可以使用 application.yaml 文件配置我们的组件。该注释用于激活负载均衡器功能,并通过参数定义配置类。@LoadBalancerClientsdefaultConfiguration

@SpringBootApplication 
@EnableFeignClients(defaultConfiguration = BookClientConfiguration.class) 
@LoadBalancerClients(defaultConfiguration = LoadBalancerConfiguration.class) 
public class AppMain { 

    public static void main(String[] args) { 	
		SpringApplication.run(AppMain.class, args);     
	} 
}

配置类定义了一个 bean 类型,并允许我们设置要使用的特定平衡算法。在下面的示例中,我们使用算法。此算法根据分配给每个节点的权重来选择服务。ServiceInstanceListSupplierweighted

@Configuration
public class LoadBalancerConfiguration {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
            .withBlockingDiscoveryClient()
            .withWeighted()
            .build(context);
    }
}

测试客户端负载均衡

我们将展示一个使用两个简单微服务的示例,一个充当服务器,另一个充当客户端。我们将客户端想象为调用作者服务的图书馆应用程序的图书服务。我们将使用 JUnit 测试实现此演示。您可以在本文底部的链接中找到该示例。

客户端将通过 OpenFeign 调用服务器。我们将使用 API 模拟工具 Hoverfly 实现一个模拟两个服务器实例上的调用的测试用例。该示例使用以下版本的 Java、Spring Boot 和 Spring Cloud。

  • Spring 启动:3.2.1
  • 春云:2023.0.0 
  • 爪哇 17

要在 JUnit 测试中使用 Hoverfly,我们必须包含以下依赖项:

<dependencies>		
  <!-- Hoverfly -->
  <dependency>
    <groupId>io.specto</groupId>
    <artifactId>hoverfly-java-junit5</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

我们将使用算法在客户端应用程序中配置负载均衡器。这意味着它将始终首选之前选择的实例(如果可用)。您可以使用如下所示的 configuration 类来实现该行为:withSameInstancePreference

@Configuration
public class LoadBalancerConfiguration {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
            .withBlockingDiscoveryClient()
            .withSameInstancePreference()
            .build(context);
    }
}

我们希望独立于外部环境测试 Client 端组件。为此,我们通过将属性设置为 .然后,我们在端口 8091 和 8092 上静态定义两个作者服务实例:eureka.client.enabledfalse

spring:
   application:
      name: book-service
   cloud:
      discovery:
         client:
            simple:
               instances:
                  author-service:
                    - service-id: author-service
                      uri: http://author-service:8091
                    - service-id: author-service
                      uri: http://author-service:8092                          
eureka:
   client: 
       enabled: false

我们用 注释我们的测试类,这将启动客户端的应用程序上下文。要使用 application.yaml 文件中配置的端口,我们将参数设置为 的值 . 我们还用 进行注释,以将 Hoverfly 集成到运行环境中。@SpringBootTestwebEnvironmentSpringBootTest.WebEnvironment.DEFINED_PORT@ExtendWith(HoverflyExtension.class)

使用 Hoverfly 域特定语言,我们模拟了服务器应用程序的两个实例,公开了端点 .我们通过方法为两者设置不同的延迟。在客户端上,我们定义了一个终端节点,该终端节点通过负载均衡器转发调用并将其定向到 REST 服务的一个实例或另一个实例。/authors/getInstanceLBendDelay/library/getAuthorServiceInstanceLBgetInstanceLB

我们将在 for 循环中执行 10 次调用。由于我们为这两个实例配置的延迟非常不同,因此我们预计大多数调用都会以最小的延迟到达服务。我们可以在下面的代码中看到测试的实现:/library/getAuthorServiceInstanceLB

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ExtendWith(HoverflyExtension.class)
class LoadBalancingTest {

    private static Logger logger = LoggerFactory.getLogger(LoadBalancingTest.class);

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testLoadBalancing(Hoverfly hoverfly) {
        hoverfly.simulate(dsl(
            service("http://author-service:8091").andDelay(10000, TimeUnit.MILLISECONDS)
                .forAll()
                .get(startsWith("/authors/getInstanceLB"))
                .willReturn(success("author-service:8091", "application/json")),
    
            service("http://author-service:8092").andDelay(50, TimeUnit.MILLISECONDS)
                .forAll()
                .get(startsWith("/authors/getInstanceLB"))
                .willReturn(success("author-service:8092", "application/json"))));

        int a = 0, b = 0;
        for (int i = 0; i < 10; i++) {
            String result = restTemplate.getForObject("http://localhost:8080/library/getAuthorServiceInstanceLB", String.class);
            if (result.contains("8091")) {
                ++a;
            } else if (result.contains("8092")) {
                ++b;
            }
            logger.info("Result: ", result);
        }
        logger.info("Result: author-service:8091={}, author-service:8092={}", a, b);
    }
}

如果我们运行测试,我们可以看到所有针对实例的调用都有 20 毫秒的延迟。您可以通过在两个延迟之间设置较低的范围来更改值,以查看结果如何变化。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SolarWinds Web Help Desk曝出严重漏洞,已遭攻击者利用

近日&#xff0c;CISA 在其 “已知漏洞”&#xff08;KEV&#xff09;目录中增加了三个漏洞&#xff0c;其中一个是 SolarWinds Web Help Desk (WHD) 中的关键硬编码凭据漏洞&#xff0c;供应商已于 2024 年 8 月底修复了该漏洞。 SolarWinds Web Help Desk 是一款 IT 服务台套…

影刀RPA实战番外:excel函数应用指南

Excel函数是用于执行特定计算、分析和数据处理任务的预定义公式。它们可处理数学计算、文本处理、逻辑判断、日期和时间运算、查找和引用数据等。例如&#xff0c;SUM函数可以计算一系列数字的总和&#xff0c;IF函数进行逻辑测试&#xff0c;VLOOKUP函数在表格中查找数据&…

HTML之表单设计

1、HTML表单 HTML表单是用于收集用户输入的信息&#xff0c;并将用户输入的内容信息传到后台服务器中。 表单是通过form标签实现。 特别注意&#xff1a;如果一些内容提交后&#xff0c;没有将内容提交给后台服务器&#xff0c;那么需要添加一个name属性&#xff0c;语法&am…

鼠标移入盒子,盒子跟随鼠标移动

demo效果&#xff1a; 鼠标移入盒子&#xff0c;按下鼠标,开启移动跟随移动模式,再次按下关闭移动模式 涉及主要属性 在元素上单击鼠标按钮时输出鼠标指针的坐标&#xff1a; var x event.pageX; // 获取水平坐标 var y event.pageY; // 获取垂直坐标元素offsetL…

JDK-23与JavaFX配置在IDEA中

一、安装 1.IDEA安装&#xff0c;可以查看CSDN 2.JDK,JavaFX安装&#xff0c;可以查看CSDN 二、配置JDK 打开IDEA&#xff0c;选择个项目&#xff0c;点击图中的设置按钮&#xff1a; 点击项目设置&#xff1a; 点击“”添加JDK&#xff0c;寻找相应的JDK目录就行 三、配置…

Python快速入门教程

目录 1. Python 简介 2. 环境准备 3. 第一个 Python 程序 4. 变量与数据类型 5. 基本操作与控制结构 6. 函数与模块 7. 实践项目 结语 Python 是一种非常友好的编程语言&#xff0c;特别适合初学者。它的语法简洁&#xff0c;容易上手&#xff0c;并且广泛应用于各种领…

机器视觉运动控制一体机在DELTA并联机械手视觉上下料应用

市场应用背景 DELTA并联机械手是由三个相同的支链所组成&#xff0c;每个支链包含一个转动关节和一个移动关节&#xff0c;具有结构紧凑、占地面积小、高速高灵活性等特点&#xff0c;可在有限的空间内进行高效的作业&#xff0c;广泛应用于柔性上下料、包装、分拣、装配等需要…

从docker中导出已经存在的容器

从docker中导出已经存在的容器,作用:创建一个容器可以给多台电脑的docker使用&#xff0c;不用重复安装环境。 操作步骤&#xff1a; (1)先运行要导出的容器&#xff0c;并在cmd终端使用docker ps 查看运行的详细信息&#xff0c;留意一下 COMMAND对应的值后面运行容器需要使用…

创建匿名管道

匿名管道&#xff1a; pipe()函数可用于创建一个管道&#xff0c;以实现进程间的通信。 头文件是#include<unistd.h>&#xff0c;参数是int类型的数组 fd[0]表示读端 fd[1]表示写端 如下代码使用pipe函数创建管道&#xff0c;并打印出来&#xff0c;最后关闭终端。 #…

力扣 简单 70.爬楼梯

文章目录 题目介绍题解 题目介绍 题解 思路分析&#xff1a; 确定dp数组以及下标的含义&#xff1a;dp[i]&#xff1a; 爬到第i层楼梯&#xff0c;有dp[i]种方法确定递推公式&#xff1a;从dp[i]的定义可以看出&#xff0c;dp[i] 可以有两个方向推出来。首先是dp[i - 1]&…

Springboot基于微信小程序的同城优惠软件的开发-计算机毕设 附源码24287

Springboot基于微信小程序的同城优惠软件的开发 摘要 随着互联网技术的发展&#xff0c;网络购物越来越受到大家的欢迎。电子商务这一概念大家都不在陌生。通过互联网进行的商品贸易范围越来越广泛&#xff0c;从经典的电子商品、到化妆品、书籍等&#xff0c;发展到小吃商品&a…

PCL学习——点云基础

点云基础 一、什么是三维点云二、获取三维点云的几种方式三、主要挑战四、什么是PCL 一、什么是三维点云 三维点云&#xff08;3D Point Cloud&#xff09;是一种用于表示三维空间中对象或场景的数据结构。在最基础的形式中&#xff0c;它是一个包含多个三维坐标点&#xff08…

SpringBoot民宿预定信息管理系统-计算机毕业设计源码89828

目 录 摘要 1 绪论 1.1 选题背景与意义 1.2研究背景 1.3论文结构与章节安排 2 民宿预定信息管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分…

Pytest日志收集器配置

前言 在pytest框架中&#xff0c;日志记录&#xff08;logging&#xff09;是一个强大的功能&#xff0c;它允许我们在测试期间记录信息、警告、错误等&#xff0c;从而帮助调试和监控测试进度。 pytest与Python标准库中的logging模块完美集成&#xff0c;因此你可以很容易地在…

Spring源码解析(35)之Spring全体系源码流程图

一、前言 画了一个spring全体系的流程图&#xff0c;spring容器创建过程&#xff0c;spring生命周期过程&#xff0c;AOP过程&#xff0c;Spring事务执行过程。 二、Spring体系源码图

【1024程序员节】之C++系列完结篇:Web编程

文章目录 一、Web编程1. 使用C标准库和第三方库2. 使用CWeb框架3. 使用C与JavaScript的集成4. 数据库交互5. 部署和运维 二、CppCMS框架构建Web应用1. 安装 CppCMS&#xff1a;2. 创建项目目录和文件3. 编写源代码4. 编译和运行5. 访问 Web 应用 三、HTTP介绍1. 请求头部字段&a…

Vue项目的创建

安装Vue工具 Vue CLI Vue CLI Vue.js 开发的标准工具&#xff0c;Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统 npm install -g vue/cli安装之后&#xff0c;你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue&#xff0c;看看是否展示出了一份所有可用命令的…

qt QApplication详解

一、概述 QApplication是Qt应用程序的基础类&#xff0c;负责设置和管理应用的环境。它的主要功能包括&#xff1a;初始化应用程序、管理事件循环、处理命令行参数、提供全局设置&#xff08;如样式和调色板&#xff09;以及创建和管理主窗口。通常在main函数中创建QApplicati…

Netty简单应用

1.服务端构建 接收客户端请求&#xff0c;打印请求消息&#xff1b;消息采用内置String作为编码与解码器&#xff1b;开启信息输入监听线程&#xff0c;发送消息至客户端&#xff1b; 1.1 服务端消息处理类 import io.netty.channel.Channel; import io.netty.channel.Chann…

React实现购物车功能

今日学习React的useReducer&#xff0c;实现了一个购物车功能 文章目录 目录 效果展示 逻辑代码 CSS代码 效果展示 逻辑代码 import {useReducer} from "react"; import ./index.css; import { message} from antd;export function ShoppingCount(){// 初始化购…