SpringCloud多机部署,负载均衡-LoadBalance

一.负载均衡

1.1问题描述

//根据应用名称获取服务列表
List<ServiceInstance> instances=discoveryClient.getInstances("product-service");
//一个微服务可能有多个实例,获取第一个
EurekaServiceInstance instance=(EurekaServiceInstance)instances.get(0);

1.根据应用名称获取服务实例列表,然后从实例列表中选择一个其中一个实例

那要是一个服务对应多个实例,流量能否合理的分配到多个实例呢?

如下操作,一个服务弄出多个实例来:

我们在启动两个product-service实例:选中要启动的实例,右键选择copy configuration

在弹出的框中选择Modify options->Add VM options(添加虚拟机参数)

添加VM options:-Dserver.poort=9091(9091是服务启动的端口号,可以自己根据情况进行修改)(意思是在 Java 虚拟机启动参数中设置一个系统属性,这里具体是将服务器的端口设置为 9091。)

像这样一共启动三个服务(把原来的那个改名为ProductServicrApplication-9090:

启动服务,访问eureka会发现product-service有三个实例,如下:

访问127.0.0.1:8080/order/1,访问结果为:

多次访问,再观察日志:

通过日志可以观察到,请求多次访问,都是同一台机器(这个信息是下面这个截图看到的)

这肯定不是我们想要看到的,我们希望三个实例可以分担请求的负荷,那么如何实现呢?

解决方案:

使用原子类中的整数,防止多线程下的线程安全问题

这里将atomicinteger提出来当成静态成员变量,那么同一个工程中就是共用一个integer,每访问一次就加一,而不是每次访问都是从一开始。

同理,将instances列表拿出来当成成员变量,就是防止每一次访问都重新获取服务实例列表。而对于getInstances方法,它的返回结果不是按顺序的,而是每一次都不一样,如果将getInstances方法放到selectOrderInfoById中,那么每一次发起请求就会重新获取服务实例列表,前三次获取的实例顺序可能是a b c,可能是b a c,也可能是a c b.然后每次都对原子整数取模,得到的下标是按顺序的,也就是1 2 3,那么就不是均衡的获取了

在方法中进行实例获取时,可以使用轮询获取

这次进行多次访问,再观察日志,就会发现这三个服务实例是轮着来的

1.2什么是负载均衡

负载均衡(LoadBalance,简称LB),是高并发,高可用系统必不可少的关键组件。

当服务流量增大时,通常会采用增加机器的方式进行扩容,负载均衡就是用来在多个机器或者其他资源中,按照一定的规则合理分配负载。

1.3负载均衡的一些实现

上述例子只是简单的轮询机制,但真实场景会更加复杂,比如根据机器的配置进行负载分配,配置高端分配的流量高,配置低的分配的流量低。

类似于企业员工:能力强的员工可以多承担一些工作。

服务多机部署时,开发人员都需要考虑负载均衡的实现,所以也出现了一些负载均衡器来帮我们实现负载均衡。

负载均衡分为服务端负载均衡和客户端负载均衡。

服务器端负载均衡

订单服务调用商品服务,商品服务就是服务端,服务端这里通过一定的算法将收到的请求分配到莫一台机器上,这就是服务端负载均衡。最常见的服务器端负载均衡器就是Nginx负载均衡器,然后通过负载均衡算法,在多个服务器之间选择一个进行访问。

客户端负载均衡器

在客户端负载均衡中,负载均衡的逻辑由客户端自己实现。客户端知道所有可用的服务实例,并根据一定的算法选择一个合适的服务实例来发起请求。

二.SpringCloud LoadBalancer

2.1给RestTemplate这个Bean添加@LoadBalancer

这里使用了@LoadBalanced注解,是的该RestTemaplate对象有了负载均衡功能,并且默认的负载均衡算法是轮询的负载均衡

2.2修改端口号为服务名称

2.3启动多个product-service实例并测试负载均衡

连续多次发起请求:127.0.0.1:8080/order/1

观察product-service的日志,就会发现请求被分配到了这三个实例上

2.4负载均衡策略

1.轮询:轮询策略是指服务器轮流处理用户的请求。这是最简单最常用的策略

2.随机选择:随机选择一个后端服务器来处理请求。

三.自定义负载均衡器

SpringCloud LoadBalancer默认的负载均衡策略是轮询策略,是现实RoundRobinLoadBalancer。现在我们来实现一个采用随机策略的负载均衡器

3.1定义随机算法对象,通过@Bean将其加载到Spring中

此处使用SpringCloudLoadBalancer提供的RandomLoadBalancer

package com.bite.order.config;import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;public class LoadBalancerConfig {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBanlancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory){String name=environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);System.out.println("============="+name);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

@Bean注解:适用于告诉Spring容器,该方法将要返回一个bean对象,可以被其他组件注入和使用。在这里,该方法是返回一个ReactorLoadBalancer<ServiceInstance>接口的负载均衡器bean

可以看到,有两个类实现了这个接口,这两个类也就是我们所说的随机负载均衡器和轮询负载均衡器。这个接口的ServiceInstance表示该负载均衡器的操作对象是服务实例列表

Environment:Spring 的Environment接口提供了对应用程序环境的访问。在这里,可以通过它来获取应用程序的配置属性。getProperty就是获取属性的意思

LoadBalanceClientFactory:是一个用于创建负载均衡客户端的工厂类。它可以提供一些方法来配置负载均衡器

最后返回的是一个随机负载均衡器的实例对象

总的来说,这段代码定义了一个方法,该方法在 Spring 容器中创建并返回一个随机负载均衡器 bean。这个负载均衡器可以根据服务实例列表选择一个随机的服务实例来处理请求,并且可以通过配置属性进行定制。

注意:该类要满足:1.不使用@Configuration注释  2.在组件扫描范围内

为什么不使用@Configuration注释?首先,如果使用了@Configuration注释,那么就会在Spring启动时将该类中被@Bean标记的方法中的bean对象创建出来,而不是在什么时候使用时再创建,这样就不具有灵活性。其次,假设有两个类都有@Configuration注释,而且两个类中都有使用@Bean注入同类型的负载均衡器,那么俩个负载均衡器都会在Spring启动时创建出来,当在某个地方使用时,编译器就不知道要使用哪一个负载均衡器了

组件扫描范围指什么:设置端口参数 - 豆包

只有放到组件扫描范围内了,这个类才能被Spring容器发现并且管理。其中定义的@Bean方法才有可能被拿出来创建Bean。如果这个类不在组件扫描范围内,这个bean的定义就没办法被发现,就无法创建Bean

3.2使用@LoadBalancerClient或者@LoadBalancerClients注解

在RestTemplate配置类上方,使用@LoadBalancerClinet或@LoadBalancerClients注解,可以对不同的服务方提供配置不同的客户端负载均衡算法策略

这样的话,就能够返回一个带有负载均衡功能的http处理工具RestTemplate实例对象

上面的@LoadBalancerClient中name制定了该负载均衡算法对哪个服务起作用,configuration标识了使用哪个类的对象作为负载均衡器。

四.服务部署

3.1准备数据

在linux终端登录mysql进行建库建表操作

修改配置文件中数据库的密码,改成linux系统中的数据库密码

product和order的都要改

3.2服务构建打包

要分别对eureka-server、product-service、order-service打包

1.pom.xml配置

<properties>项目属性和变量:定义项目中可能用到的常量或变量值,可在整个文件中被引用,也可在其他配置文件中被引用。

 

<profiles>元素用于定义不同的构建配置文件,构建配置文件通常用于定义软件项目在构建过程中的各种参数和设置,以实现不同环境下的定制化构建。可以针对开发(dev)、测试(test)、生产(prod)等不同环境设置不同的构建参数。

每个配置文件都有一个唯一的 ID 和一组属性。在这个例子中,每个配置文件只有一个属性 profile.name,分别设置为 “dev” 和 “prod”。

在 Maven 项目中,配置文件可以用于在不同的环境中设置不同的构建参数、资源过滤、插件配置等。例如,可以根据不同的环境设置不同的数据库连接信息、服务器地址等。

由于product-service和order-service都涉及到数据库密码的修改,所以这段配置要添加到这两个子项目的pom文件中

2.备份并修改yml配置文件

将prod环境的yml文件中的数据库密码改成linux文件下的MySQL密码

然后在每个项目的主配置文件application.yml加下面的配置:

​
spring:profiles:active: @profile.name@​

这里的profile.name就是去maven中读取这个变量

项目启动后,并不是只选择其中一个配置文件进行操作。首先,application.yml通常作为基础配置文件,其中可以包含一些通用的配置属性

然后,根据激活的环境(通过spring.profiles.active属性指定),会加载相应的特定环境配置文件。例如:如激活的是开发环境,那么application-dev.yml中的配置会与application.yml中的配置合并,共同生效。

那要是在多个配置文件中有相同的属性,特定环境配置文件中的属性会覆盖application.yml中的属性

总之,在SpringBoot项目中,项目启动时多个配置文件(application.yml,application-dev.yml,application-prod.yml等)都会被扫描,但会根据环境选择特定的配置文件与基础配置文件合并生效,以满足不同环境下的配置需求。

pom.xml与applicatiom.yml的区别与用途:https://www.doubao.com/thread/wc88d3dc72ec47658

3.依次对三个项目打包

和SpringBoot项目的打包方式一样,依次对三个项目进行package即可

先点一下clean(当执行 “clean” 阶段时,Maven 会删除项目的 target 目录。这个目录通常包含编译后的字节码文件、打包生成的文件(如 JAR、WAR 文件)、测试报告等在构建过程中生成的临时文件。)“clean” 阶段为后续的构建阶段创造了一个干净的环境。这意味着在执行其他构建阶段(如 compile、test、package 等)之前,项目的构建状态被重置,确保构建结果的准确性和一致性。例如,如果在上一次构建中出现了错误或者需要进行重大的更改,执行 “clean” 阶段可以确保所有的临时文件和旧的构建产物都被删除,以便进行新的构建。

clean完再打包

3.3启动服务

1.上传Jar包到云服务器上

第一次上传需要安装lrzsz(lrzsz是一款在 Linux 系统中常用的文件传输工具。)

apt install lrzsz

直接拖动文件到xshell窗口,上传成功(上传之前可以建一个springcloud的文件夹,具体操作如下)

2.启动服务

启动服务后,我们希望看到日志,所以可以先创建一个日志目录:

进行eureka-server,product-service,order-service的启动

#后台启动eureka-server,并设置输出日志到logs/erueka.log
nohup java -jar eureka-server-1.0-SNAPSHOT.jar >logs/eureka.log &
#后台启动product-service,并设置输出日志到logs/product.log
nohup java -jar product-serivce-1.0-SNAPSHOT.jar >logs/product.log &
#后台启动order-service,并设置输出日志到logs/order.log
nohup java -jar order-service-1.0-SNAPSHOT.jar >logs/order.log &

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

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

相关文章

聊聊Flink:Flink中的时间语义和Watermark详解

该篇主要讲Flink中的时间语义、Flink 水印机制以及Flink对乱序数据的三重保障。 一、Flink的三种时间语义 1.1 Event Time Event Time指的是数据流中每个元素或者每个事件自带的时间属性&#xff0c;一般是事件发生的时间。由于事件从发生到进入Flink时间算子之间有很多环节&…

CSS基础选择器与div布局

基础选择器一 全局选择器 可以与任何元素匹配&#xff0c;优先级最低&#xff0c;不推荐使用 *{margin: 0;padding: 0;}元素选择器 HTML文档中的元素&#xff0c;p、b、div、a、img、body等。 标签选择器&#xff0c;选择的是页面上所有这种类型的标签&#xff0c;所以经常…

npm上传自己封装的插件(vue+vite)

一、npm账号及发包删包等命令 若没有账号&#xff0c;可在npm官网&#xff1a;https://www.npmjs.com/login 进行注册。 在当前项目根目录下打开终端命令窗口&#xff0c;常见命令如下&#xff1a; 1、登录命令&#xff1a;npm login&#xff08;不用每次都重新登录&#xff0…

ODC 如何精确呈现SQL耗时 | OceanBase 开发者工具解析

前言 在程序员或DBA的日常工作中&#xff0c;编写并执行SQL语句如同日常饮食中的一餐一饭&#xff0c;再寻常不过。然而&#xff0c;在使用命令行或黑屏客户端处理SQL时&#xff0c;常会遇到编写难、错误排查缓慢以及查询结果可读性不佳等难题&#xff0c;因此&#xff0c;图形…

华为USG5500防火墙配置NAT

实验要求&#xff1a; 1.按照拓扑图部署网络环境&#xff0c;使用USG5500防火墙&#xff0c;将防火墙接口加入相应的区域&#xff0c;添加区域访问规则使内网trust区域可以访问DMZ区域的web服务器和untrust区域的web服务器。 2.在防火墙上配置easy-ip&#xff0c;使trust区域…

三角波生成函数

% 设置时间范围和采样频率 t 0:0.01:2; % 时间从0到2秒&#xff0c;步长为0.01秒% 定义频率 f 和角频率 theta f 5; % 频率为5Hz theta 2 * pi * f * t;% 初始化输出向量 y zeros(size(t));% 根据给定的公式计算 y for k 1:fy y (-1)^(k-1)*(2 /(k * pi)) * sin(k * the…

Lc70--319.两个数组的交集(二分查找)---Java版

1.题目描述 2.思路 用集合求交集&#xff0c;因为集合里面的元素要满足不重复、无序、唯一。使得集合在去重、查找和集合操作&#xff08;如交集、并集、差集等&#xff09;中非常高效和方便。 3.代码实现 class Solution {public int[] intersection(int[] nums1, int[] nu…

操作系统实验 C++实现生产者-消费者问题

实验目的 1、进一步加深理解进程同步的概念 2、加深对进程通信的理解 3、了解Linux下共享内存的使用方法 实验内容 1、按照下面要求&#xff0c;写两个c程序&#xff0c;分别是生产者producer.c以及customer.c 2、一组生产者和一组消费者进程共享一块环形缓冲区 使用共…

无人机在森林中的应用!

一、森林资源调查 无人机可以利用遥感技术快速获取所需区域高精度的空间遥感信息&#xff0c;对森林图斑进行精确区划。相较于传统手段&#xff0c;无人机调查具有低成本、高效率、高时效的特点&#xff0c;尤其在地理环境条件不好的区域&#xff0c;调查人员无法或难以到达的…

Android学生信息管理APP的设计与开发

1. 项目布局设计 页面1&#xff1a;学生信息添加页面 采用线性布局&#xff0c;页面中控件包含TextView、editView、Button等。 布局核心代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http…

AI(12)-飘带

1.【钢笔工具】画第一条曲线 2.【钢笔工具】画第二条曲线 3-全选两条曲线-【对象】-【混合】-【混合选项】-【指定的步数】-【15】 3-1-【对象】-【混合】-【建立】 4-双击打开【渐变工具】 4-1-【类型&#xff1a;线性】 4-2-点击切换【描边】在上方 4-3-关闭【填色】 4-4-点…

智能指针原理、使用和实现——C++11新特性(三)

目录 一、智能指针的理解 二、智能指针的类型 三、shared_ptr的原理 1.引用计数 2.循环引用问题 3.weak_ptr处理逻辑 四、shared_ptr的实现 五、定制删除器 六、源码 一、智能指针的理解 问题&#xff1a;什么是智能指针&#xff1f;为什么要有智能指针&#xff1f;智…

NIST 发布后量子密码学转型战略草案

美国国家标准与技术研究所 (NIST) 发布了其初步战略草案&#xff0c;即内部报告 (IR) 8547&#xff0c;标题为“向后量子密码标准过渡”。 该草案概述了 NIST 从当前易受量子计算攻击的加密算法迁移到抗量子替代算法的战略。该草案于 2024 年 11 月 12 日发布&#xff0c;开放…

使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法

在使用uniapp开发微信小程序时候&#xff0c;过多的引入uni_modules的组件库&#xff0c;会导致主包文件过大&#xff0c;导致无法上传微信小程序&#xff0c;主包要求大小不超过1.5MB.分包大小每个不能超过2M。 解决方法&#xff1a;分包。 1.对每个除了主页面navbar的页面进…

WPF窗体基本知识-笔记-命名空间

窗体程序关闭方式 命名空间:可以理解命名空间的作用为引用下面的控件对象 给控件命名:一般都用x:Name,也可以用Name但是有的控件不支持 布局控件(容器)的类型 布局控件继承于Panel的控件,其中下面的border不是布局控件,panel是抽象类 在重叠的情况下,Zindex值越大的就在上面 Z…

【android USB 串口通信助手】stm32 源码demo 单片机与手机通信 Android studio 20241118

android 【OTG线】 接 下位机STM32【USB】 通过百度网盘分享的文件&#xff1a;USBToSerialPort.apk 链接&#xff1a;https://pan.baidu.com/s/122McdmBDUxEtYiEKFunFUg?pwd8888 提取码&#xff1a;8888 android 【OTG线】 接 【USB转TTL】 接 【串口(下位机 SMT32等)】 需…

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args 目录…

使用IDEA+Maven实现MapReduced的WordCount

使用IDEAMaven实现MapReduce 准备工作 在桌面创建文件wordfile1.txt I love Spark I love Hadoop在桌面创建文件wordfile2.txt Hadoop is good Spark is fast上传文件到Hadoop # 启动Hadoop cd /usr/local/hadoop ./sbin/start-dfs.sh # 删除HDFS的hadoop对应的input和out…

Spring Cloud Ribbon 实现“负载均衡”的详细配置说明

1. Ribbon 介绍 Ribbon 是什么 &#xff1f; 1.Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端&#xff0c;负载均衡的工具 2.Ribbon 主要功能是提供客户端负载均衡算法和服务调用 3.Ribbon 客户端组件提供一系列完善的配置项如“连接超时&#xff0c;重试” 4…

TSMC12nm工艺数字IC后端实现难点都有哪些?

大家知道咱们社区近期TSMC 12nm ARM Cortexa-A72(1P9M 6Track Metal Stack)即将开班。这里小编要强调一点:不要认为跑了先进工艺的项目就会很有竞争力&#xff01;如果你仅仅是跑个先进工艺的flow&#xff0c;不懂先进工艺在数字IC后端实现上的不同点&#xff0c;为何有这样的不…