微服务学习-Nacos 注册中心实战

news2025/1/27 23:40:28

1. 注册中心的设计思路

1.1. 微服务为什么会用到注册中心?

服务与服务之间调用需要有服务发现功能;例如订单服务调用库存服务,库存服务如果有多个,订单服务到底调用那个库存服务呢(负载均衡器),如果某个库存服务不可用了(心跳上报),如何知道不可用呢,这里就牵涉到服务的注册与发现。

1.2. 如何设计一个注册中心?

注册中心肯定需要存储服务的信息,服务的 ip 和端口,健康状态等,服务的注册与发现功能,心跳上报,健康检查功能是必要的。

1.3. 注册中心应该包含哪些常见功能?

服务的注册与发现、服务的健康检查、服务心跳,集群的话可能就需要服务同步。

1.4. 注册中心的设计思路

2. Nacos 注册中心核心概念和功能

2.1. 核心概念

官网 Nacos 的概念及架构:Nacos 概念 | Nacos 官网

  • 服务(Service)

服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。

  • 服务注册中心(Service Registry)

服务注册中心,它是服务,其实例及源数据的数据库。

  • 服务元数据(Service Metadata)

服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。

  • 命名空间(Namespace)

用来进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 DataID 的配置。

Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

  • 服务分组(Group)

不同的服务可以归类到同一分组。

2.2. 核心功能

  • 服务注册

Nacos Client 会通过发送 REST 请求的方式向 Nacos Server 注册自己的服务,提供自身的元数据,比如 ip 地址、端口等信息。Nacos Server 接受到注册请求后,就会把这些元数据信息存储在一个双层的内存 Map 中。

  • 服务心跳

在服务注册后,Nacos Client 会维护一个定时心跳来持续通知 Nacos Server,说明服务一直处于可用状态,防止被剔除。默认 5s 发送一次心跳。

  • 服务同步

Nacos Server 集群之间会互相同步服务实例,用来保证服务信息的一致性。

  • 服务发现

服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个 REST 请求给 Nacos Server,获取上面注册的服务清单,并且缓存在 Nacos Client 本地,同时会在 Nacos Client 本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存。

  • 服务健康检查

Nacos Server 会开启一个定时任务用来检查注册服务实例的健康情况,对于超过 15s 没有收到客户端心跳的实例会将它的 healthy 属性置为 false (客户端服务发现时不会发现),如果某个实例超过 30s 没有收到心跳,直接剔除该实例(被剔除的实力如果恢复发送心跳则会重新注册)。

3. 微服务整合 Nacos 注册中心常用配置项详解

3.1. 准备测试环境

会员服务:icoolkj-mall-user

订单服务:icoolkj-mall-order01

速通版:git checkout v2.0.0 版本:

icoolkj-microservices-code 标签 - Gitee.com

启动服务,获取会员订单信息:

http://localhost:8580/api/user/getOrderByUserId?userId=1

3.2. 服务逻辑隔离配置

3.2.1. 数据模型

Nacos 数据模型 Key 由三元组唯一确定,Namespace 默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。

3.2.2. Namespace 隔离设计

命名空间(Namespace)用于进行租户(用户)粒度的隔离,Namespace 的常用场景之一是不同环境的隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

3.2.2.1. 在 nacos 控制台创建一个 dev 的命名空间

3.2.2.2. 配置订单服务 namespace 为 dev
cloud:
  nacos:
    discovery:
      server-addr: icoolkj-mall-nacos-server:8848
      namespace: dev  # 指定 dev 开发环境命名空间
3.2.2.3. 重启订单服务,测试

用户调用订单接口能否查询到订单信息

问题:无法调用订单服务,提示:No instances available for icoolkj-mall-order01

原因:icoolkj-mall-order01 和 icoolkj-mall-user 使用了不同的 namespace,导致服务隔离,icoolkj-mall-user 无法发现可用的 icoolkj-mall-order01 服务。

3.2.3. group 服务分组隔离

不同的服务可以归类到同一个分组,group 也可以起到服务隔离的作用,yml 中可以通过 spring.cloud.nacos.discovery.group 参数配置。group 更多应用场景是配置分组。

3.2.3.1. 配置订单服务分组为 group1
cloud:
  nacos:
    discovery:
      server-addr: icoolkj-mall-nacos-server:8848
      namespace: dev  # 指定 dev 开发环境命名空间
      group: group1 # 指定 group1 分组
3.2.3.2. 重启订单服务,测试

用户调用订单接口能否查询到订单信息

问题:无法调用订单服务,提示:No instances available for icoolkj-mall-order01

原因:icoolkj-mall-order01 和 icoolkj-mall-user 使用了不同的分组,导致服务隔离,icoolkj-mall-user 无法发现可用的 icoolkj-mall-order01 服务。

3.3. 服务领域模型

注册中心的核心数据是服务名称和它对应的网络地址,当服务注册了多个实例时,需要对不健康的实力进行过滤或者对实例的一些特征进行流量的分配,就需要再实例上存储一些例如 IP、端口、健康状态、权重等属性。随着服务的规模扩大,需要再整个服务级别设定一些权限规则,以及对所有实例都生效的一些开关,于是在服务级别又会设立一些属性。我们发现单个服务的实力又会划分为多个子集的需求,例如一个服务是多个机房部署的,可能需要对每个机房的实例做不同的胚子,这样有需要在服务和实例之间再设定一个数据级别。

Nacos 在经过内部多年生产经验,提炼除的数据模型,则是一种服务-集群-实例的三层模型。这样基本可以满足服务在所有场景下的数据存储和管理。

3.3.1. 集群配置
spring:
  cloud:
    nacos:
      discovery:
        server-addr: icoolkj-mall-nacos-server:8848
        namespace: dev  # 指定 dev 开发环境命名空间
        #group: group1 # 指定 group1 分组
        cluster-name: BJ # 指定集群名称 北京机房

重启订单服务,测试,不同的集群的微服务之间是可以调用的,一般情况不隔离;可以实现本地集群优先调用,例如上海订单先调用上海机房集群,如果上海集群出问题了,可以调用其他地方集群。

3.3.2. 临时实例和持久化实例
3.3.2.1. 健康检查的方式

临时实例使用客户端上报模式,需要能够自动摘除不健康实例,而且无需持久化存储实例。

持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳,所以不能自动摘除下线的实例。

3.3.2.2. 适用场景

上层业的业务服务,例如订单服务,库存服务都可以上报心跳,都是临时实例;

一些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。

3.3.2.3. 如何配置
# 持久化实例
spring.cloud.nacos.discovery.ephemeral: false

Nacos 默认注册的都是临时实例。

常见错误:

Current service DEFAULT_GROUP@@icoolkj-mall-order01 is ephemeral service, can't register persistent instance. 在 Nacos2.0 中将是否持久化的数据抽象至服务级别,且不再允许一个服务同时存在持久化实例和非持久化实例,实例的持久化属性继承自服务的持久化属性。

The Raft Group [naming_persistent_service_v2] did not find the Leader node 要配置持久化实例必须得是 nacos 集群模式。

3.4. Nacos 安全配置

官方参考文档:配置鉴权 | Nacos 官网

Nacos 是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险。

3.4.1. 如何实现安全配置
3.4.1.1. nacos server 端

nacos-server-2.3.2/nacos/conf/application.properties 添加如下配置:

# 开启认证
nacos.core.auth.enabled=true
# 配置自定义身份识别的key(不可为空)和value(不可为空)
#这两个属性是auth的白名单,用于标识来自其他服务器的请求。
#具体实现见 com.alibaba.nacos.core.auth.AuthFilter
# 用于服务端api鉴权,注意:并不是nacos的用户名密码
nacos.core.auth.server.identity.key=authKey
nacos.core.auth.server.identity.value=nacosSecurty

# 默认鉴权插件用于生成用户登陆临时accessToken所使用的密钥,使用默认值有安全风险  (2.2.0.1后无默认值)
#自定义密钥时,推荐将配置项设置为Base64编码的字符串,且原始密钥长度不得低于32字符。
nacos.core.auth.plugin.nacos.token.secret.key=pDEYqLTBvWAp16osN6dxLvZTo9RfNsY3DfhI

注意:在2.2.0.1版本后,社区发布版本需要自行填充nacos.core.auth.plugin.nacos.token.secret.key的值,否则无法启动节点。

随机字符串生产工具:随机字符串生成 - 程序员工具箱 - 在线工具

注意:鉴权开关是修改之后立马生效的,不需要重启服务端。

3.4.1.2. nacos client 端

nacos server 开启鉴权后,微服务提示 user not found!

微服务的 application.yml 中添加如下配置:

spring:
  application:
    name: icoolkj-mall-user
  cloud:
    nacos:
      discovery:
        server-addr: icoolkj-mall-nacos-server:8848
        namespace: dev  # 指定 dev 开发环境命名空间
        #group: group1 # 指定 group1 分组
        #cluster-name: BJ # 指定集群名称 北京机房
        username: nacos
        password: nacos

默认用户名密码都是 nacos,可以在 ncaos 控制台创建新用户。

4. Nacos 高可用集群最佳实践

4.1. nacos 部署方式

单机模式:用于测试和单机使用。默认使用的是 derby 数据库。

注意:单机模式下 Linux 运行Nacos:sh startup.sh -m standalone

集群模式:用于生产环境,确保高可用。

4.2. 官方文档

集群部署说明

4.3. 集群部署架构图

最终方案:nginx + 三个节点 nacos 集群 + mysql

为保证数据一致性,集群环境需要用 mysql(三个节点都可以访问到 mysql)替换内部的 derby 数据库。

4.4. 搭建步骤

官方部署手册:Nacos支持三种部署模式

4.4.1. 前期环境准备
4.4.1.1. 三台 Linux 虚拟机
# 准备三台 centOS7 服务器
200.8.9.16:8848
200.8.9.17:8848
200.8.9.18:8848

安装好 JDK,需要 1.8 及其以上版本;建议:2 核 CPU,4G 内存及其以上。

注意:nacos2.3.2 不能使用 OpenJDK,会出现开启鉴权后控制台无论使用什么密码登录都显示账号密码错误问题。

4.4.1.2. 准备好 Nacos2.3.2 的安装包

下载地址:发布历史 | Nacos 官网

4.4.2. 配置集群配置文件

在 nacos 的解压目录 nacos/的conf 目录下,有配置文件 cluster.conf,请每行配置成 ip:port。

#解压进入nacos 安装目录
unzip nacos-server-2.3.2.zip
cd nacos/
mv conf/cluster.conf.example conf/cluster.conf
vim  conf/cluster.conf

# ip:port 
200.8.9.16:8848
200.8.9.17:8848
200.8.9.18:8848

注意:不要使用 localhost 或 127.0.0.1,针对多网卡环境,Nacos 可以指定网卡或 IP

当本地环境比较复杂的时候,Nacos 服务在启动的时候需要选择运行时使用的 IP 或者网卡。

#多网卡IP选择
# ip-address 参数可以直接设置 nacos 的 ip
#该参数设置后,将会使用这个 IP 去 cluster.conf 里进行匹配,请确保这个 IP 的值在 cluster.conf 里是存在的
nacos.inetutils.ip-address=200.8.9.16

# use-only-site-local-interfaces 参数可以让nacos使用局域网 ip ,这个在 nacos 部署的机器有多网卡时很有用,可以让 nacos 选择局域网网卡
nacos.inetutils.use-only-site-local-interfaces=true

# ignored-interfaces 支持网卡数组,可以让 nacos 忽略多个网卡
nacos.inetutils.ignored-interfaces[0]=eth0
nacos.inetutils.ignored-interfaces[1]=eth1

# preferred-networks 参数可以让 nacos 优先选择匹配的 ip,支持正则匹配和前缀匹配
nacos.inetutils.preferred-networks[0]=200.8.9.
nacos.inetutils.preferred-networks[0]=200.8.9.(25[0-5]|2[0-4]\\d|((1d{2})|([1-9]?\\d))),200.8.9.(25[0-5]|2[0-4]\\d|((1d{2})|([1-9]?\\d)))
4.4.3. 开启默认鉴权插件

修改 conf 目录下的 application.properties 文件

nacos.core.auth.enabled=true
nacos.core.auth.server.identity.key=${自定义,保证所有节点一致}
nacos.core.auth.server.identity.value=${自定义,保证所有节点一致}
nacos.core.auth.plugin.nacos.token.secret.key=${自定义,保证所有节点一致}
4.4.4. 配置数据源

使用外置 mysql 数据源,生产使用建议至少主备模式

4.4.4.1. 初始化 mysql 数据库

sql 脚本:nacos-server-2.3.2/nacos/conf/mysql-schema.sql

4.4.4.2. 修改 application.properties 配置
spring.sql.init.platform=mysql
db.num=1
db.url.0=jdbc:mysql://200.8.9.16:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
4.4.4.3. 常见错误

java.lang.RuntimeException: [db-load-error]load jdbc.properties error

检查 nacos 的 mysql 连接,数据库的 ip、数据库、用户名和密码。

4.4.5. 分别启动三个 nacos 节点

以 200.8.9.16 为例,进入 nacos 目录,启动 nacos。

sh bin/startup.sh

4.4.6. 访问 nacos 管理界面

登录 200.8.9.16:8848/nacos,用户名和密码默认都是 nacos

5. 小结

通过 Nacos 注册中心可以实现微服务的注册与发现。生产环境搭建高可用集群模式。

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

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

相关文章

MySQL数据库 - 语法知识

一 数据模型 1 关系型数据库管理系统(RDBMS) 概念:建立在关系模型基础上,有多张相互连接的二维表组成的数据库。 特点: 使用表存储数据,格式统一,便于维护。使用SQL语言操作,标准…

有限元分析学习——Anasys Workbanch第一阶段笔记(15)接触间隙处理与赫兹接触

目录 0 序言 1 接触的间隙处理 1.1 结果对比 1.2 处理方法 2 赫兹接触 0 序言 本章主要介绍间隙出现时的三种解决方法,齿轮点蚀/表面剥落涉及的赫兹接触的一些理论知识。 1 接触的间隙处理 在实际产品过程中,很多时候由于设计问题,原本…

查询本周一到周五的数据

查询sql SELECT CASEWHEN TO_CHAR(T.BEGINDATE, D) 2 THEN 周一WHEN TO_CHAR(T.BEGINDATE, D) 3 THEN 周二WHEN TO_CHAR(T.BEGINDATE, D) 4 THEN 周三WHEN TO_CHAR(T.BEGINDATE, D) 5 THEN 周四WHEN TO_CHAR(T.BEGINDATE, D) 6 THEN 周五END AS DAY_NAME,T.COLUMN1,T.COL…

【Linux】命令为桥,存在为岸,穿越虚拟世界的哲学之道

文章目录 Linux基础入门:探索操作系统的内核与命令一、Linux背景与发展历史1.1 Linux的起源与发展1.2 Linux与Windows的对比 二、Linux的常用命令2.1 ls命令 - "List"(列出文件)2.2 pwd命令 - "Print Working Directory"&#xff08…

2025美赛美国大学生数学建模竞赛A题完整思路分析论文(43页)(含模型、可运行代码和运行结果)

2025美国大学生数学建模竞赛A题完整思路分析论文 目录 摘要 一、问题重述 二、 问题分析 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码(仅供参考) 4.1.4问题1样例代码运行结果&…

http的请求体各项解析

一、前言 做Java开发的人员都知道,其实我们很多时候不单单在写Java程序。做的各种各样的系统,不管是PC的 还是移动端的,还是为别的系统提供接口。其实都离不开http协议或者https 这些东西。Java作为编程语言,再做业务开发时&#…

深入探究分布式日志系统 Graylog:架构、部署与优化

文章目录 一、Graylog简介二、Graylog原理架构三、日志系统对比四、Graylog部署传统部署MongoDB部署OS或者ES部署Garylog部署容器化部署 五、配置详情六、优化网络和 REST APIMongoDB 七、升级八、监控九、常见问题及处理 一、Graylog简介 Graylog是一个简单易用、功能较全面的…

微信开发者工具的快捷键

微信开发者工具的快捷键 微信开发者工具的所有快捷键

科家多功能美发梳:科技赋能,重塑秀发新生

在繁忙的都市生活中,头皮健康与秀发养护成为了现代人不可忽视的日常课题。近日,科家电动按摩梳以其卓越的性能和创新设计,赢得了广大消费者的青睐。这款集科技与美学于一身的美发梳,不仅搭载了2亿负离子、6000次/分钟的声波振动等前沿技术,更融入了650nm聚能环红光与415nm强劲蓝…

JVM面试题解,垃圾回收之“分代回收理论”剖析

一、什么是分代回收 我们会把堆内存中的对象间隔一段时间做一次GC(即垃圾回收),但是堆内存很大一块,内存布局分为新生代和老年代、其对象的特点不一样,所以回收的策略也应该各不相同 对于“刚出生”的新对象&#xf…

批量修改图片资源的属性。

Unity版本2022.3 如图,比如我们想要修改图片的属性的时候,大部分都是 TextureImporter importer (TextureImporter)AssetImporter.GetAtPath("Assets/1.png"); // 获取文件 importer.xxxxxxx xxxxxxx; // 修改属性到这里没什么问题&#xf…

vim 中粘贴内容时提示: -- (insert) VISUAL --

目录 问题现象:解决方法:问题原因: 问题现象: 使用 vim 打开一个文本文件,切换到编辑模式后,复制内容进行粘贴时有以下提示: 解决方法: 在命令行模式下禁用鼠标支持 :set mouse …

一个功能强大、操作易用的屏幕录制.Net开源工具 草稿箱

推荐一款免费开源的屏幕录制工具,凭借其强大的功能和用户友好的界面,受到非常多人喜欢! 01 项目简介 该工具不仅支持全屏录制,还提供区域录制、游戏录制和摄像头录制等多种模式。不管是录制软件操作、游戏、直播、网络教学、课件…

JAVASE入门十脚-红黑树,比较器,泛型

红黑树Set,ArrayList数组,LinkedList链表 AVL二叉树 红黑树 插入节点一般是红色 treeSet()底层是treeMap,利用红黑树来实现 package ContainerDemo1;import java.util.Objects;public class PersonDemo {private String name;private int age;public PersonDemo(){}public P…

总结8..

#include <stdio.h> // 定义结构体表示二叉树节点&#xff0c;包含左右子节点编号 struct node { int l; int r; } tree[100000]; // 全局变量记录二叉树最大深度&#xff0c;初始为0 int ans 0; // 深度优先搜索函数 // pos: 当前节点在数组中的位置&#xff0c…

RabbitMQ 仲裁队列 -- 解决 RabbitMQ 集群数据不同步的问题

1.问题情景 当我们搭建了一个 RabbitMQ 集群后是存在问题的,也就是数据不同步.我们可以来看下是什么问题 1. 1 添加队列 ①:选择虚拟机(需要保证操作⽤户对当前虚拟机有操作权限) ②:设置队列名称 ③:持久化队列 ④:指定队列所在主节点,其他为从节点分别以 rabbit 节点和 rabb…

环境变量配置与问题解决

目录 方法 配置了还是运行不了想要的东西 解决方案 为什么 解决方案 方法 方法一&#xff1a;此电脑右击-属性-相关链接-高级系统设置-环境变量&#xff08;N&#xff09;-系统变量里面找到Path-三个确定】 方法二&#xff1a;winr cmd 黑框输入sysdm.cpl&#xff0c;后面…

js 数据组合,一级结构组合成父子嵌套数组结构

1.方法 buildDeptTree(deptData) { //构建树状部门// 创建一个 map 来存储 deptId 和对应的部门对象const deptMap new Map();// 初始化每个部门对象的 children 属性为空数组deptData.forEach(dept > {dept.children [];deptMap.set(dept.deptId, dept);});// 构建树形结…

Python GUI 开发 | PySide6 PyQt6 学习手册

本文是个 Python GUI 开发的目录&#xff0c;方便读者系统性学习的&#xff0c;笔者后续会满满填充此目录中的内容&#xff0c;感兴趣的小伙伴可以关注一手。&#xff08;主要是偏向 PySide6 方向的&#xff09; 0x01&#xff1a;PySide6 & PyQt6 基础入门 0x0101&#xff…

扣子平台音频功能:让声音也能“智能”起来

在数字化时代&#xff0c;音频内容的重要性不言而喻。无论是在线课程、有声读物&#xff0c;还是各种多媒体应用&#xff0c;音频都是传递信息、增强体验的关键元素。扣子平台的音频功能&#xff0c;为开发者和内容创作者提供了一个强大而灵活的工具&#xff0c;让音频的使用和…