微服务_注册中心Eureka与Nacos

学习顺序建议

1.先理解「硬编码调用为什么不行」,明白注册中心诞生的意义;

2.学习 Eureka,掌握经典注册中心工作原理;

3.学习 LoadBalancer 负载均衡原理;

4.学习 Nacos,同时掌握注册 + 配置两大功能;

5.最后对比 Eureka 与 Nacos 选型差异,理解为什么生产环境普遍选用 Nacos。

一、微服务服务调用的原始方案与存在的常见问题

这是微服务场景下订单服务调用商品服务的基础实现:

  1. 查询订单信息,拿到订单中的 productId
  2. 通过 RestTemplate 拼接固定地址 http://127.0.0.1:9090/product/{id} 远程调用商品服务;
  3. 获取商品实体 ProductInfo,塞入订单实体 OderInfo 中,实现订单携带商品详情返回。

可能会出现一些问题,比如接口公开安全性,商品服务一旦更换 IP、端口、部署多实例,代码直接失效;无法实现集群负载均衡。

二.引入注册中心后的微服务架构流程

完整流程

  1. 服务注册 :服务提供者启动时,将自身服务名称、IP、端口信息上报给注册中心保存。
  2. 服务发现:服务消费者启动 / 发起调用前,向注册中心查询「目标服务名称」对应的可用 IP 地址列表。
  3. 远程调用:消费者拿到提供者实例地址后,直接发起远程调用;结合负载均衡策略,可轮流调用多个服务实例。
  4. 注册中心职责:维护「服务名称 ↔ 实例 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

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

1.添加注解

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

负载均衡策略

负载均衡策略是⼀种思想, ⽆论是哪种负载均衡器, 它们的负载均衡策略都是相似的. Spring Cloud LoadBalancer 仅⽀持两种负载均衡策略: 轮询策略 和 随机策略
Spring Cloud LoadBalancer 默认负载均衡策略是 轮询策略, 实现是 RoundRobinLoadBalancer, 如果
服务的消费者如果想采⽤随机的负载均衡策略, 也⾮常简单.

  1. 定义随机算法对象, 通过 @Bean 将其加载到 Spring 容器中
  2. 使⽤ @LoadBalancerClient 或者 @LoadBalancerClients 注解,只有⼀个服务提供者, 所以使⽤@LoadBalancerClient

五、Nocos

Nocas的安装

windows
1.下载地址 https://github.com/alibaba/nacos/releases/tag/2.2.3
下载zip文件解压
2.修改单机模式:修改startup.cmd文件

3.启动成功后, 访问Nacos链接: http://IP:port/nacos

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-service
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020

  1. 修改IP为项⽬名
  2. 为restTemplate添加负载均衡注解 @LoadBalanced

    启动服务

开启nacos负载均衡:

spring:
cloud:
loadbalancer:
nacos:
enabled: true
1.支持服务上线下线

2.服务配置权重

3.同集群优先访问:
spring:
cloud:

复制代码
  nacos:
    discovery:
      server-addr: 
      cluster-name: BJ #设置集群名称

Nacos健康检测

一、客户端主动上报机制

  1. 客户端通过心跳上报方式告知 Nacos 注册中心自身健康状态,默认心跳间隔 5 秒

  2. Nacos 规则:

    • 超过 15 秒 未收到心跳 → 将实例标记为不健康;

    • 超过 30 秒 未收到心跳 → 直接删除该实例。

二、服务端反向探测机制

  1. Nacos 主动探测客户端健康状态,默认探测间隔 20 秒

  2. 健康检查失败后,实例仅被标记为不健康,不会立刻删除

服务节点,默认为临时实例,临时实例采用客户端主动上报,非临时实例是服务器反向探测

Nacos会记录每一个实例的IP,端口号以及实例类型,不允许临时实例与非临时实例变化如果修改需要,修改Nacos的相关数据,即删除raft文件夹,nacos\data\protocol\raft。

再修改yml文件

复制代码
Spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为非临时实例

Nacos环境隔离

企业开发中, ⼀个服务会分为开发环境, 测试环境和⽣产环境.,这些环境是相互隔离的,
Nacos提供了namespace(命名空间)来实现环境的隔离,不同的namaspace的服务不可⻅。
1.创建Namespace

2.配置Namespace

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

不同环境不能相互通信:

Nacos配置中心

添加配置获取配置

1.添加配置 在Nacos控制台添加配置项点击创建配置


微服务启动前, 需要先获取nacos中配置, 并与application.yml配置合并. 在微服务运⾏之前, Nacos要求必须使⽤ bootstrap.yml 配置⽂件来配置Nacos Server 地址
2.引入依赖

复制代码
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.yml Nacos 配置是在容器启动早期、解析 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}.${file
extension}
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:基于推送模式,服务列表有变化实时推送订阅者,服务器客户端保持心跳连接

相关推荐
倔强的石头_1 小时前
一次MongoDB迁移之后,我开始重新理解融合数据库
数据库
正在走向自律2 小时前
【金仓数据库征文】从 MySQL 迁移到金仓数据库:哈工大智能造价项目的一次信创改造实践
数据库·mysql·性能优化·国产数据库·数据库迁移·信创适配·金仓数据库征文
奇特認2 小时前
MySQL 集群技术 1.源码编译
数据库·mysql
爱和冰阔落2 小时前
【Linux】两个毫无关系的进程怎么通信?命名管道 FIFO 从原理到 Server/Client 实战
android·linux·数据库·c++·vim
范什么特西11 小时前
回答知识总结04(redis)
数据库·redis·缓存
码农颜12 小时前
5.4.1 锁分类
java·数据库·mysql
云深处@13 小时前
【数据库】MySQL 入门
数据库·学习·mysql
梦远星帆13 小时前
SQLyog社区版下载
数据库·mysql·sqlyog
科力锐品牌君14 小时前
行业龙头|科力锐全链路防勒索 + 多中心容灾方案,构筑河南翔宇医疗业务安全闭环!
网络·数据库·分布式·安全·数据安全·备份