SpringCloud服务拆分:Nacos服务注册中心 + LoadBalancer服务负载均衡使用
SpringCloud中Nacos服务注册中心 + LoadBalancer服务负载均衡使用
- 前言
- Nacos
- 工作流程
- nacos安装
- docker安装
- window安装
- 运行nacos
- 微服务集成nacos
- 高级特性
- 1.服务集群
- 配置方法
- 效果图
- 模拟服务实例宕机
- 2.权重配置
- 3.环境隔离
- 如何启动集群节点
- 本地启动多个节点方法
- LoadBalancer
- 集成LoadBalancer
- LoadBalancer流程
- 源码跟踪
- 自定义负载均衡算法
- 使用自定义负载均衡算法
- 结语
😀大家好!我是向阳🌞,一个想成为优秀全栈开发工程师的有志青年!
📔今天来说一说SpringCloud中Nacos服务注册中心 + LoadBalancer服务负载均衡使用。
前言
本篇文章主要是使用Nacos来注册服务实例,使用Nacos来管理这些服务实例,然后使用LoadBalancer让服务消费方负载均衡调用服务提供方。
这里有一些代码准备,Contorller的代码我就不贴了,贴一个order服务远程调用user服务,获取订单对应的用户信息。
这里使用的是RestTemplate来进行调用远程服务,后续会用OpenFeign来进行替换优化。
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;/*** 查询订单(携带用户信息)** @param orderId* @return*/@Overridepublic Order findOrderByOrderId(Long orderId) {Order order = orderMapper.findOrderByOrderId(orderId);User user = restTemplate.getForObject("http://ssgw-cloud-user/api/user/findUserByUserId/" + order.getUserId(),User.class);order.setUser(user);return order;}
}
Nacos
官方文档地址:Nacos文档地址
Nacos有多个特性,这里我们主要介绍的是他的服务发现和服务健康监测这个特性,他还有个我常用的特性,那就是动态配置服务,以后可能会说到。
我们把服务都注册到Nacos里面,Nacos会对服务进行实时的健康检查,阻止向不健康的主机或服务实例发送请求。
工作流程
通过注册中心可以对服务提供方和服务消费方进行解耦。具体的工作模式如下图所示:
工作流程说明:
- 服务提供方在启动的时候,会向注册中心注册自己服务的详情信息 (ip、端口号等) 。在注册中心中会维护一张服务清单,保存这些注册信息,注册中心需要以心跳的方式(30s,服务向注册中心发送心跳)去监测清单中的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。
- 服务消费方向服务注册中心咨询服务,并获取所有服务的实例清单,然后,按照指定的负载均衡算法从服务清单中选择一个服务实例进行访问。
- 每当服务提供方有节点不可用后,服务消费方会重新缓存可用的提供方信息(ip、端口号等)。
nacos安装
docker安装
直接在linux虚拟机中用docker进行以下命令即可。
# 拉取镜像
docker pull nacos/nacos-server:v2.2.2# 创建容器
docker run --name nacos -e MODE=standalone -p 8848:8848 -p 9848:9848 -d nacos/nacos-server:v2.2.2# nacos2.x的版本新增了一个客户端与服务端的gRpc的通讯端口号9848
window安装
不同的版本有不同的注意事项,可以去官方文档查阅,或者具体的细节可以查看其他博客,这里不详细赘述。
二进制包下载地址
运行nacos
docker的运行在上面已经提到了,docker run xxx就已经运行了。
Window版本的docker配置文件默认是单机模式启动,所以我们运行nacos要加上 standalone 这个命令。
startup.cmd -m standalone
运行成功的页面,nacos的默认端口是8848,我们访问:http://localhost:8848/nacos 即可访问到图形化界面,默认账号密码都是 nacos。
微服务集成nacos
在pom.xml中加入以下依赖:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
在application.yml中加入以下配置:
spring:# 配置nacos注册中心的地址cloud:nacos:discovery:server-addr: localhost:8848 # 如果在虚拟机安装,则改成你对应的ip地址application: name: spzx-cloud-user # 每一个服务注册到nacos注册中心都需要提供一个服务名称,order微服务注册的时候需要更改微服务名称
加入对应的配置文件后,在nacos图形化界面就可以看到以下信息,这里我已经启动了3个user服务,所以 ssgw-cloud-user 的实例数为3。
高级特性
1.服务集群
在实际生产环境中,为了保证每一个服务的高可用,那么,此时就需要去构建服务集群,但是,并不是说把所有的服务都部署在一个机房里。而是将多个服务分散的部署到不同的机房中,每一个机房的服务可以看做成是一个集群。
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:上海机房内的order微服务应该优先访问同机房的user微服务。
配置方法
配置yml文件:
spring:cloud:nacos:discovery:cluster-name: SH # 配置服务所属集群
集成nacos的负载均衡算法,也是在yml文件中配置,配置了之后,就会按照服务集群来进行访问对应的服务实例,访问默认是随机访问。
spring:cloud:loadbalancer:nacos:enabled: true
一个服务不同实例配置不同的集群方法和下面如何启动集群节点方法一样,这里贴个图。
我们这里用户服务,两个配置BJ,两个配置SH,订单服务配置了SH,根据上面的讲述,如果我们访问订单服务的接口,我们应该优先访问的是两个SH的用户服务。
配置了服务集群后,nacos的服务实例有所变化,如下面两张图。
效果图
我们访问订单的接口,查看用户服务的控制台,我们可以看到只有配置了SH的两个用户服务控制台信息有打印SQL语句,说明被只有这两个服务被调用了。
其余三个我就不贴图了…
模拟服务实例宕机
我们可以在nacos的图形化界面中下线按钮来下线对应的服务实例,这样就模拟了服务宕机场景,此时我们下线两个SH的用户服务实例,我们访问订单接口,此时访问就会访问两个BJ的服务实例,如下图所示。
此时只会调用在配置在BJ的两个服务实例中。
其余三个我就不贴图了…
2.权重配置
我们可以对不同的服务进行权重配置,比如性能好的服务器权重就可以大一点,性能差的服务器泉州就可以小一点。
这个我们可以直接在nacos图形化界面进行配置,点击编辑后,即可在弹出的弹窗进行权重配置。
我们还可以在yml文件中进行配置:
spring:cloud:nacos:discovery:weight: 0.1
3.环境隔离
在实际的开发过程中,可能会存在很多个软件环境:开发环境、测试环境、生产环境。
nacos也是支持多环境隔离配置的,在nacos中是通过namespace来实现多环境的隔离。
完整的服务注册数据存储结构如下所示:
namespace + group 才可以确定具体的微服务实例。默认情况下,所有service、group都在同一个namespace,名为public。
在nacos的图形化界面就可以进行namespace的添加。
给微服务添加名称空间的配置,来指定该微服务所属环境,这里修改order的application.yml文件,改为dev:
spring:# 配置nacos注册中心的地址cloud:nacos:discovery:namespace: dev # 配置服务实例所属名称空间
这个时候order和其他的user实例已经不在同一个namespace命名空间下了,这个时候我们再次访问接口就会报错,因为访问不到了。
控制台报错找不到对应的实例:
我们也可以分配组,在yml配置文件中进行配置:
spring:# 配置nacos注册中心的地址cloud:nacos:discovery:namespace: dev # 配置服务实例所属名称空间group: ORDER_GROUP
如何启动集群节点
我们启动多个user节点,让order服务负载调用user节点。
本地启动多个节点方法
我们对原本的user服务右键点击,选择Copy Configuration来拷贝配置,进而修改新的配置,我们这里修改端口,防止端口冲突启动不起来。
服务名称可改可不改使用默认的也可以,但是一定要覆盖配置文件中的端口号。
选择Override configuration properties后,添加以下配置来覆盖原有的配置,约定大于配置,走的就是我们这里配置的端口。
配置完毕后,启动就是下图所示的结果。
LoadBalancer
集成LoadBalancer
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
Spring Cloud LoadBalancer 是Spring Cloud中负责客户端负载均衡的模块,其主要原理是通过选择合适的服务实例来实现负载均衡。
客户端负载均衡:就是负载均衡算法由客户端提供,默认是轮询负载均衡,就是每个服务被依次调用。
我们多此访问我们项目的接口,可以从控制台中发现,三个用户服务的控制台中各有一条SQL查询信息,说明每个都被调用了一次。
http://localhost:10200/api/order/findOrderByOrderId/101
LoadBalancer流程
Spring Cloud LoadBalancer的底层采用了一个拦截器【LoadBalancerInterceptor】,拦截了RestTemplate发出的请求,对地址做了修改。
执行流程说明:
-
通过 LoadBalancerInterceptor 请求拦截器拦截我们的 RestTemplate请求:http://ssgw-cloud-user/api/user/findUserByUserId/1
-
获取请求的url,然后,从请求的url中获取服务提供方的主机名称(ssgw-cloud-user)
-
然后,调用LoadBalancerClient中的execute方法,将服务提供方的名称传递过去
-
在LoadBalancerClient的choose方法中通过ReactiveLoadBalancer.Factory从Nacos注册中心中获取服务列表以及负载均衡算法实例对象
-
通过ReactiveLoadBalancer从服务列表中选择一个服务实例地址,然后,发起远程调用
源码跟踪
首先我们进入到 LoadBalancerInterceptor 的 intercept 方法,可以看到我们调用远程服务的uri和服务名称serviceName。
紧接着进入到 LoadBalancerClient 的 execute 方法,这个方法主要来处理服务id和用户请求,我们主要看他的 choose 方法。
我们从choose方法可以看出来,我们的负载均衡器是我们在配置文件中配置的 NacosLoadBalancer 负载均衡器。
紧接着调用负载均衡器的 choose 方法,从服务列表中选择一个服务实例对象。
如果我们注释掉配置文件中的集成nacos的负载均衡算法,我们可以得到负载均衡器变成了默认的RR负载均衡器也就是轮询调度负载均衡器(RoundRobinLoadBalancer)。
自定义负载均衡算法
详细注释在代码中都有,这里不多赘述。
public class CustomLoadBalancerConfiguration {/*** @param environment: 用于获取环境属性配置,其中LoadBalancerClientFactory.PROPERTY_NAME表示该负载均衡器要应用的服务名称。* @param loadBalancerClientFactory: 是Spring Cloud中用于创建负载均衡器的工厂类,通过getLazyProvider方法获取ServiceInstanceListSupplier对象,以提供可用的服务列表。* ServiceInstanceListSupplier:用于提供ServiceInstance列表的接口,可以从DiscoveryClient或者其他注册中心中获取可用的服务实例列表。* @return*/@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
使用自定义负载均衡算法
这里使用的是 RestTemplate 来远程调用其他的服务接口(后期会换成 OpenFeign),所以我们在 RestTemplateConfiguration 类上面加上 @LoadBalancerClients 注解来指定我们要调用哪个服务实例,指定使用我们自定义的负载均衡算法来进行调用。
@Configuration
@LoadBalancerClients(value = {@LoadBalancerClient(name = "ssgw-cloud-user", configuration = CustomLoadBalancerConfiguration.class)
})
public class RestTemplateConfiguration {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}
结语
至此我们就完成了我们的主题《SpringCloud服务拆分:Nacos服务注册中心 + LoadBalancer服务负载均衡使用》,更多的细节和使用方法还等着我们去探索,加油吧👍!
——👦[作者]:向阳256
——⏳[更新]:2025.5.8
——🥰本人技术有限,如果有不对指正需要更改或者有更好的方法,欢迎到评论区留言。
相关文章:

SpringCloud服务拆分:Nacos服务注册中心 + LoadBalancer服务负载均衡使用
SpringCloud中Nacos服务注册中心 LoadBalancer服务负载均衡使用 前言Nacos工作流程nacos安装docker安装window安装 运行nacos微服务集成nacos高级特性1.服务集群配置方法效果图模拟服务实例宕机 2.权重配置3.环境隔离 如何启动集群节点本地启动多个节点方法 LoadBalancer集成L…...
Spring AI 集成 DeepSeek V3 模型开发指南
Spring AI 集成 DeepSeek V3 模型开发指南 前言 在人工智能飞速发展的当下,大语言模型不断推陈出新,DeepSeek AI 推出的开源 DeepSeek V3 模型凭借其卓越的推理和问题解决能力备受瞩目。与此同时,Spring AI 作为一个强大的框架,…...

Apache Doris 使用指南:从入门到生产实践
目录 一、Doris 核心概念 1.1 架构组成 1.2 数据模型 二、Doris 部署方式 2.1 单机部署(测试环境) 2.2 集群部署(生产环境) 三、数据操作指南 3.1 数据库与表管理 3.2 数据导入方式 3.2.1 批量导入 3.2.2 实时导入 3.…...

26届秋招收割offer指南
26届暑期实习已经陆续启动,这也意味着对于26届的同学们来说,“找工作”已经提上了日程。为了帮助大家更好地准备暑期实习和秋招,本期主要从时间线、学习路线、核心知识点及投递几方面给大家介绍,希望能为大家提供一些实用的建议和…...

拷贝多个Excel单元格区域为图片并粘贴到Word
Excel工作表Sheet1中有两个报表,相应单元格区域分别定义名称为Report1和Report2,如下图所示。 现在需要将图片拷贝图片粘贴到新建的Word文档中。 示例代码如下。 Sub Demo()Dim oWordApp As ObjectDim ws As Worksheet: Set ws ThisWorkbook.Sheets(&…...
Kafka消息队列之 【消费者分组】 详解
消费者分组(Consumer Group)是 Kafka 提供的一种强大的消息消费机制,它允许多个消费者协同工作,共同消费一个或多个主题的消息,从而实现高吞吐量、可扩展性和容错性。 基本概念 消费者分组:一组消费者实例的集合,这些消费者实例共同订阅一个或多个主题,并通过分组来协调…...

【Bluedroid】蓝牙 SDP(服务发现协议)模块代码解析与流程梳理
本文深入剖析Bluedroid蓝牙协议栈中 SDP(服务发现协议)服务记录的全生命周期管理流程,涵盖初始化、记录创建、服务搜索、记录删除等核心环节。通过解析代码逻辑与数据结构,揭示各模块间的协作机制,包括线程安全设计、回…...

中国自动驾驶研发解决方案,第一!
4月28日,IDC《中国汽车云市场(2024下半年)跟踪》报告发布,2024下半年中国汽车云市场整体规模达到65.1亿元人民币,同比增长27.4%。IDC认为,自动驾驶技术深化与生成式AI的发展将为汽车云打开新的成长天花板,推动云计算在…...

Kubernetes(k8s)学习笔记(四)--入门基本操作
本文通过kubernetes部署tomcat集群,来学习和掌握kubernetes的一些入门基本操作 前提条件 1.各个节点处于Ready状态; 2.配置好docker镜像库(否则会出现ImagePullBackOff等一些问题); 3.网络配置正常(否则即使应用发布没问题,浏…...

【项目篇之统一硬盘操作】仿照RabbitMQ模拟实现消息队列
统一硬盘操作 创建出实例封装交换机的操作封装队列的操作封装绑定的操作封装消息的操作总的完整代码: 我们之前已经使用了数据库去管理交换机,绑定,队列 还使用了数据文件去管理消息 此时我们就搞一个类去把上述两个部分都整合在一起&#…...
【基础复习笔记】计算机视觉
目录 一、计算机视觉基础 1. 卷积神经网络原理 2. 目标检测系列 二、算法与模型实现 1. 在PyTorch/TensorFlow中实现自定义损失函数或网络层的步骤是什么? 2. 如何设计一个轻量级模型用于移动端的人脸识别? 3. 描述使用过的一种注意力机制&#…...

基于 GO 语言的 Ebyte 勒索软件——简要分析
一种新的勒索软件变种,采用Go 语言编写,使用ChaCha20进行加密,并使用ECIES进行安全密钥传输,加密用户数据并修改系统壁纸。其开发者EvilByteCode曾开发过多种攻击性安全工具,现已在 GitHub 上公开 EByte 勒索软件。尽管该勒索软件声称仅用于教育目的,但滥用可能会导致严重…...

0基础 | STM32 | STM32F103C8T6开发板 | 项目开发
注:本专题系列基于该开发板进行,会分享源代码 F103C8T6核心板链接: https://pan.baidu.com/s/1EJOlrTcProNQQhdTT_ayUQ 提取码:8c1w 图 STM32F103C8T6开发板 1、黑色制版工艺、漂亮、高品质 2、入门级配置STM32芯片(SEM32F103…...

南京大学OpenHarmony技术俱乐部正式揭牌 仓颉编程语言引领生态创新
2025年4月24日,由OpenAtom OpenHarmony(以下简称“OpenHarmony”)项目群技术指导委员会与南京大学软件学院共同举办的“南京大学OpenHarmony技术俱乐部成立大会暨基础软件与生态应用论坛”在南京大学仙林校区召开。 大会聚焦国产自主编程语言…...

主场景 工具栏 植物卡牌的渲染
前置知识:使用easyx图形库 1.IMAGE内存变量存储的是一张位图(图像),存储了像素数据(颜色,尺寸等) 2.loadimage(&变量名,"加载的文件路径")表示从文件中加载图像到变量中 3. saveimage("文件路径", &变…...
计算机网络:深入分析三层交换机硬件转发表生成过程
三层交换机的MAC地址转发表生成过程结合了二层交换和三层路由的特性,具体可分为以下步骤: 一、二层MAC地址表学习(基础转发层) 初始状态 交换机启动时,MAC地址表为空,处于学习阶段。 数据帧接收与源MAC学习 当主机A发送数据帧到主机B时,交换机会检查数据帧的源MAC地址。…...

Java三大基本特征之多态
多态(Polymorphism)是面向对象编程(OOP)的三大特性之一(另外两个是 封装 和 继承),它允许 同一个行为具有不同的表现形式。在 Java 中,多态主要通过 方法重写(Override&a…...

OpenCV 基于生物视觉模型的工具------模拟人眼视网膜的生物视觉机制类cv::bioinspired::Retina
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::bioinspired::Retina 是 OpenCV 中用于仿生视觉处理的一个类,它基于生物视觉模型进行图像预处理。该算法特别适用于动态范围调整…...

前端跨域问题怎么在后端解决
目录 简单的解决方法: 添加配置类: 为什么会跨域 1. 什么是源 2. URL结构 3. 同源不同源举🌰 同源例子 不同源例子 4. 浏览器为什么需要同源策略 5. 常规前端请求跨域 简单的解决方法: 添加配置类: packag…...

Python小程序:上班该做点摸鱼的事情
系统提醒 上班会忘记一些自己的事,所以你需要在上班的的时候突然给你弹窗,你就知道要做啥了 源码 这里有一个智能家居项目可以看看(开源) # -*- coding:utf-8 -*- """ 作者:YTQ 日期: 2025年04日29 21:51:24 """ impor…...
企业级AI革命!私有化部署开源大模型:数据安全+自主可控,打造专属智能引擎
AI大模型浪潮席卷全球,但企业面临两大痛点:数据隐私风险高、公有云服务难定制! 如何既享受大模型的强大能力,又能保障核心数据安全?私有化部署开源大模型强势破局——将顶尖AI能力“装进”企业内网,数据0外…...

飞云分仓操盘副图指标操作技术图文分解
如上图,副图指标-飞云分仓操盘指标,指标三条线蓝色“首峰线”,红色“引力1”,青色“引力2”,多头行情时“首峰线”和“引力1”之间显示为红色,“引力1”和“引力2”多头是区间颜色显示为紫色。 如上图图标信…...

基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)
效果图 代码 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…...

【MongoDB篇】MongoDB的副本集操作!
目录 引言第一节:副本集的核心概念:它是什么?为什么需要它?🤔🧠第二节:副本集的“骨架”:成员与数据同步机制 👑🔄❤️🔥第三节:生死…...

Kubernetes 集群优化实战手册:从零到生产级性能调优
一、硬件资源优化策略 1. 节点选型黄金法则 # 生产环境常见节点规格(AWS示例) - 常规计算型:m5.xlarge (4vCPU 16GB) - 内存优化型:r5.2xlarge (8vCPU 64GB) - GPU加速型:p3.2xlarge (8vCPU V100 GPU)2. 自动扩缩容…...

【Redis分布式】主从复制
🔥个人主页: 中草药 🔥专栏:【中间件】企业级中间件剖析 一、主从复制 在分布式系统之中为了解决单点问题(1、可用性问题,该机器挂掉服务会停止2、性能支持的并发量是有限的)通常会把数据复制多…...

用递归实现各种排列
为了满足字典序的输出,我采用了逐位递归的方法(每一位的所能取到的最小值都大于前一位) 1,指数型排列 #include<bits/stdc.h> using ll long long int; using namespace std; int a[10];void printp(int m) {for (int h …...

测试用例介绍
文章目录 一、测试用例基本概念1.1 测试用例基本要素 二、测试用例的设计方法2.1 基于需求的设计方法2.2 等价类2.3 边界值2.4 错误猜测法2.6 场景设计法2.7 因果图2.5 正交排列 三、综合:根据某个场景去设计测试用例(万能公式)四、如何使用F…...

phpstudy升级新版apache
1.首先下载要升级到的apache版本,这里apache版本为Apache 2.4.63-250207 Win64下载地址:Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压, 将Apache24复制一份到ph…...
在一台服务器上通过 Nginx 配置实现不同子域名访问静态文件和后端服务
一、域名解析配置 要实现通过不同子域名访问静态文件和后端服务,首先需要进行域名解析。在域名注册商或 DNS 服务商处,为你的两个子域名 blog.xxx.com 和 api.xxx.com 配置 A 记录或 CNAME 记录。将它们的 A 记录都指向你服务器的 IP 地址。例如&#x…...