微服务_注册中心Eureka与Nacos
学习顺序建议
1.先理解「硬编码调用为什么不行」,明白注册中心诞生的意义;
2.学习 Eureka,掌握经典注册中心工作原理;
3.学习 LoadBalancer 负载均衡原理;
4.学习 Nacos,同时掌握注册 + 配置两大功能;
5.最后对比 Eureka 与 Nacos 选型差异,理解为什么生产环境普遍选用 Nacos。
一、微服务服务调用的原始方案与存在的常见问题
这是微服务场景下订单服务调用商品服务的基础实现:
- 查询订单信息,拿到订单中的
productId; - 通过
RestTemplate拼接固定地址http://127.0.0.1:9090/product/{id}远程调用商品服务; - 获取商品实体
ProductInfo,塞入订单实体OderInfo中,实现订单携带商品详情返回。


可能会出现一些问题,比如接口公开安全性,商品服务一旦更换 IP、端口、部署多实例,代码直接失效;无法实现集群负载均衡。
二.引入注册中心后的微服务架构流程
完整流程
- 服务注册:服务提供者启动时,将自身服务名称、IP、端口信息上报给注册中心保存。
- 服务发现:服务消费者启动 / 发起调用前,向注册中心查询「目标服务名称」对应的可用 IP 地址列表。
- 远程调用:消费者拿到提供者实例地址后,直接发起远程调用;结合负载均衡策略,可轮流调用多个服务实例。
- 注册中心职责:维护「服务名称 ↔ 实例 IP 地址」的映射关系,同时检测服务健康状态,剔除宕机节点。

主流注册中心组件
Nacos、Eureka、Consul、ZooKeeper。
CAP理论是分布式系统最基础最关键的理论,
C:强一致性,何时访问结果一致,
A:可用性,对于请求都有响应,但是可能是错误的
P:分区容错性:在网络分区情况下依然可以提供服务
一致性:
客户端向数据集群发送一个数据修改的请求,数据集群回复一个响应,响应分为两种,一种是主库收到请求,但数据未同步,随着时间推移会达到一致,另一种是主库收到请求,数据已经同步从库。
强一致性:无论何时,主库从库对外提供的服务保持一致。
弱一致性:随着时间推移最终会达到一致。

因为P是必须保证的,所以A与P只能实现一个
三、Eureka
搭建注册中心
1.创建项目

2.pom加入Eureka依赖
<!--Eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3.配置文件,加入Eurka相关配置
server:
port: 10010
spring:
application:
name: eureka-server
eureka:
instance:
hostname: localhost
client:
fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false
register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.
service-url:
# 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4.启动类,开启Eurka功能


服务注册:
1.加入Eureka依赖
<!-- 正确:Eureka客户端,用来注册到注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.修改配置信息
server:
port: 9090
spring:
application:
name: product-service
datasource:
url: jdbc:mysql://localhost:3306/cloud_product?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #自动驼峰转换
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/
3.启动测试
服务发现:
1.加入Eureka依赖
<!-- 正确:Eureka客户端,用来注册到注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.修改配置信息
server:
port: 8080
spring:
application:
name: order-service
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #自动驼峰转换
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/
3.修改远程调用代码

4.启动测试


四、负载均衡
什么是负载均衡
启动了 3 个 product-service 商品服务实例(端口 9090、9091、9092)并注册到注册中心。
订单服务发起远程调用时,始终固定访问 192.168.32.1:9090 这一台实例,请求没有分发到另外两台商品节点,集群多实例完全没起到分担压力的作用,也就是没有负载均衡效果。


我们启动多个实例, 希望可以分担其他机器的负荷, 那么如何实现呢?解决方法:
使用
AtomicInteger原子计数器实现轮询算法,每次请求序号自增,对实例总数取模选中不同服务节点。



轮流请求

SpringCloud LoadBalance
- 作用:Spring Cloud 官方推出的客户端负载均衡组件,用来替代已经停止维护的 Netflix Ribbon,是目前 SpringCloud 体系默认负载均衡方案。
- 客户端负载均衡含义:负载均衡逻辑运行在服务消费者(订单服务)内部,而非独立网关;消费者本地缓存服务实例列表,本地算法挑选节点转发请求。
- 适配:兼容 Nacos/Eureka/Consul 所有注册中心,同时支持同步 RestTemplate、响应式 WebClient、OpenFe
1.添加注解

2.修改远程调用代码,把IP和端口号改成应用名

负载均衡策略
负载均衡策略是⼀种思想, ⽆论是哪种负载均衡器, 它们的负载均衡策略都是相似的. Spring Cloud LoadBalancer 仅⽀持两种负载均衡策略: 轮询策略 和 随机策略


五、Nocos
Nocas的安装
windows



Linux:
1.上传zip文件并且解压:

2.如果需要,修改端口号
3.启动Nacos
命令:bash startup.sh -m standalone
启动成功后, 访问Nacos链接: http://IP:port/nacos
nacos的使用
1.父工程pom文件引⼊Spring Cloud Alibaba依赖:
<properties><spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version></properties><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency>
2.再order-service和product-service引入nacos依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
3.配置nacos地址
spring:application:name: product-servicecloud:nacos:discovery:server-addr: 110.41.51.65:10020



开启nacos负载均衡:
spring:cloud:loadbalancer:nacos:enabled: true

spring:cloud:nacos: discovery: server-addr: cluster-name: BJ #设置集群名称

Nacos健康检测
一、客户端主动上报机制
-
客户端通过心跳上报方式告知 Nacos 注册中心自身健康状态,默认心跳间隔 5 秒;
-
Nacos 规则:
-
超过 15 秒 未收到心跳 → 将实例标记为不健康;
-
超过 30 秒 未收到心跳 → 直接删除该实例。
-
二、服务端反向探测机制
-
Nacos 主动探测客户端健康状态,默认探测间隔 20 秒;
-
健康检查失败后,实例仅被标记为不健康,不会立刻删除。

服务节点,默认为临时实例,临时实例采用客户端主动上报,非临时实例是服务器反向探测
Nacos会记录每一个实例的IP,端口号以及实例类型,不允许临时实例与非临时实例变化如果修改需要,修改Nacos的相关数据,即删除raft文件夹,nacos\data\protocol\raft。
再修改yml文件
Spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
Nacos环境隔离

spring:cloud:nacos:discovery:namespace: 命名空间ID



Nacos配置中心
添加配置获取配置


spring: application: name: product-service cloud: nacos: config: server-addr: 118.31.239.155
spring.application.name 需要和nacos配置管理的Data ID⼀致spring.cloud.nacos.config.server-addr 为Nacos Server的地址
3.编写程序

@Value的配置对应nacos创建的配置内容

测试:

设置命名空间
刚刚明明改改 application.yml 的 namespace为什么bootstrap.yml又再次修改
关键原因:Nacos 配置加载顺序
Spring 加载配置优先级:
bootstrap.yml(最先加载) > application.ymlNacos 配置是在容器启动早期、解析 bootstrap 阶段就去远程拉取配置; 如果你的namespace写在application.yml里: 拉取 Nacos 配置的时候,程序还没读取到 application.yml 的 namespace,此时默认使用public命名空间拉配置; 等后面读到 application.yml 的 namespace 时,配置早已加载完毕,自然不会切换 dev 命名空间的配置。现象表现
- 服务注册:会按照 application.yml 的 namespace,注册到 dev 命名空间;
- 配置拉取:启动拉配置阶段没读到 dev 命名空间配置,依旧从 public 拉配置。
在bootstrap.yml文件设置namespace,改为dev的命名空间ID




Data ID
dataId 的完整格式如下: ${prefix}-${spring.profiles.active}.${file-extension}1.prefix 默认为 spring.application.name 的值, 也可以通过配置项spring.cloud.nacos.config.prefix 来配置.2.spring.profiles.active 即为当前环境对应的 profile. 当 spring.profiles.active为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${fileextension}3.file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。⽬前只⽀持 properties和 yaml 类型. 默认为properties.优先级:product-service-dev.properties > product-service.properties > product-service
删除配置项product-service-dev.properties

删除配置项product-service.properties

六、Nacos与Eureka区别
相同点:都支持服务注册和服务拉取
区别:
1.功能:Nacos额外提供配置中心和DNS服务等功能
2.CAP理论:Eureka遵循AP原则,Nacos可以切换AP与CP原则,默认AP
Nacos根据配置识别CP或者AP模式,如果注册Nacos的Client的节点是临时节点,那么这个Nacos对这个Client节点的效果是AP,反之CP
3.服务发现:Eurca:基于拉模式,Eureka Client 会定期从Server拉服务,有缓存,默认30秒拉一次
Nacos:基于推送模式,服务列表有变化实时推送订阅者,服务器客户端保持心跳连接
更多推荐








所有评论(0)