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.rhkb.cn/news/476317.html

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

相关文章

『 Linux 』文件与网络套接字的内部关系

文章目录 回顾进程控制块socket与文件的关系wait_queue_head_t文件与套接字相关的调用方法系统中的套接字网络协议栈与方法集报文的管理 回顾进程控制块 每个进程都存在着自己的PCB结构体,即task_struct结构体,这个结构体是用来描述一个进程的; /* 已省略部分代码 */ struct t…

科研实验室的数字化转型:Spring Boot系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理实验室管理系统的相关信息成为必然。开发合…

【前端】CSS修改div滚动条样式

示例 分别是滚动条默认样式和修改后的样式 代码 <div class"video-list"><div class"list-item" onclick"videoinfo(100)"><img src"/index/images/coverimg/方和谦.png"><div class"txt">国医大…

【AIGC】如何使用高价值提示词Prompt提升ChatGPT响应质量

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | 提示词Prompt应用实例 文章目录 &#x1f4af;前言&#x1f4af;提示词英文模板&#x1f4af;提示词中文解析1. 明确需求2. 建议额外角色3. 角色确认与修改4. 逐步完善提示5. 确定参考资料6. 生成和优化提示7. 生成最终响…

centos安装jenkins

本机使用虚拟机centos 7.9.2009 安装gitlab&#xff0c;本机的虚拟机ip地址是 192.168.60.151&#xff0c; 步骤记录如下 1、下载jenkins&#xff0c;安装jenkins之前需要安装jdk jdk和jenkins的版本对应关系参考&#xff1a;Redhat Jenkins Packages Index of /redhat-stable…

使用redis-shake工具进行redis的数据同步

前言&#xff1a; 工作中将常遇到测试环境和正式环境的数据同步或者需要进行数据迁移&#xff0c;对于mysql数据库的方案倒是不少&#xff0c;但是redis中如何快速便捷的迁移呢&#xff1f;答案是阿里云提供的:redis-shake RedisShake是阿里云基于豌豆荚开源的redis-port进行…

04 —— Webpack打包CSS代码

加载器css-loader &#xff1a;解析css代码 webpack 中文文档 | webpack中文文档 | webpack中文网 加载器style-loader&#xff1a;把解析后的css代码插入到DOM style-loader | webpack 中文文档 | webpack中文文档 | webpack中文网 准备css代码&#xff0c;放到src/login目…

Nacos实现IP动态黑白名单过滤

一些恶意用户&#xff08;可能是黑客、爬虫、DDoS 攻击者&#xff09;可能频繁请求服务器资源&#xff0c;导致资源占用过高。因此我们需要一定的手段实时阻止可疑或恶意的用户&#xff0c;减少攻击风险。 本次练习使用到的是Nacos配合布隆过滤器实现动态IP黑白名单过滤 文章…

SAP PI/PO Proxy2JDBC SQL_QUERY动态接口示例

目录 背景&#xff1a; 完整demo步骤&#xff1a; IR: ID: SPROXY: 测试代码&#xff1a; 注意点&#xff1a; 背景&#xff1a; 中途临时帮客户项目做其他功能&#xff0c;项目上有部分开发项需要通过PO去第三方数据库取数&#xff0c;项目上的开发对PO不太熟&#xf…

如何使用本地大模型做数据分析

工具&#xff1a;interpreter --local 样本数据&#xff1a; 1、启动分析工具 2、显示数据文件内容 输入&#xff1a; 显示/Users/wxl/work/example_label.csv 输出&#xff1a;(每次输出的结果可能会不一样&#xff09; 3、相关性分析 输入&#xff1a; 分析客户类型与成…

中间件--laravel进阶篇

laravel版本11.31,这中间件只有3种,分别是全局中间件,路由中间件,控制器中间件。相比thinkphp8,少了一个应用中间件。 一、创建中间件 laravel创建中间件可以使用命令的方式创建,非常方便。比如php artisan make:middleware EnsureTokenIsValid。EnsureTokenIsValid是中间…

一维卷积神经网络(1D-CNN)

一维卷积神经网络&#xff08;1D Convolutional Neural Network, 1D CNN&#xff09;是卷积神经网络的一种变体&#xff0c;专门用于处理序列数据&#xff0c;如时间序列、文本等。 一、基本结构 一维卷积神经网络的基本结构与二维卷积神经网络&#xff08;2D CNN&#xff09;类…

Java中的TreeSet集合解析

记一下java流处理的操作 1.去重&#xff0c;按照billTypeCode去重 list list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getBillTypeCode()))), ArrayList::new)); 排序&#x…

vue中mixin(混入)的使用

目录 mixin(混入) 使用方式 第一步定义混合 ​编辑 第二步使用混入 局部混入 全局混合 mixin(混入) 功能&#xff1a;可以把多个组件共用的配置提取成一个混入对象 使用方式 第一步定义混合 { data(){....}, methods:{....} .... } 第二步使用混入 …

vue中路由缓存

vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后&#xff0c;再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件&#xff0c;或者切换分页到…

Easyexcel(1-注解使用)

相关文章链接&#xff1a; Easyexcel&#xff08;1-注解使用&#xff09; 版本依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.3</version> </dependency>ExcelProperty…

Vue3 -- mock数据完整配置并调试【项目集成6】

引言&#xff1a; ‌Mock在前端开发中的作用主要是模拟后端接口数据&#xff0c;以便前端开发者能够提前进行页面和功能的开发、调试&#xff0c;而无需等待后端提供真实的接口数据‌。Mock数据可以加速前后端开发的协同&#xff0c;避免因数据延迟导致的开发阻塞‌。【摘自百…

开源许可协议

何同学推动了开源协议的认识&#xff0c;功不可没&#xff0c;第一次对开源有了清晰的认识&#xff0c;最宽松的MIT开源协议 源自OSC开源社区&#xff1a;何同学使用开源软件“翻车”&#xff0c;都别吵了&#xff01;扯什么违反MIT

数据结构(顺序栈——c语言实现)

栈的基本概念&#xff1a; 栈是限制在一端进行插入操作和删除操作的线性表&#xff08;俗称堆栈&#xff09;&#xff0c;允许进行操作的一端称为“栈顶”&#xff0c;另一固定端称为“栈底”&#xff0c;当栈中没有元素时称为“空栈” 特点&#xff1a;先进后出&#xff08;FI…

【智谱清言-注册_登录安全分析报告】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…