当前位置: 首页 > news >正文

Nacos环境搭建 -- 服务注册与发现

为什么需要服务治理

在未引入服务治理模块之前,服务之间的通信是服务间直接发起并调用来实现的。只要知道了对应服务的服务名称、IP地址、端口号,就能够发起服务通信。比如A服务的IP地址为192.168.1.100:9000,B服务直接向该IP地址发起请求就可以获取对应的数据。但是,随着集群架构的搭建,服务的增多,集群架构的搭建,手动配置各个服务的实例清单就会变得越来越复杂,当集群规模发生改变、服务实例发生改变(数量或者ip等)改变,维护这种硬编码的配置内容需要消耗太多的开发资源。如果使用nginx等中间件,确实也可以实现,但是也会出现问题,比如两个服务集群之间无法直接通信,进而导致调用成本的增加,因为增加了一次网络消耗。还有当集群规模发生改变时,维护起来也是十分麻烦。

服务治理包含很多方面,在这主要讲解服务治理中的三个核心问题:服务注册、服务发现和服务的健康检查机制。

注册中心原理,见下图:

img

  1. 服务启动时会将自己的服务信息(服务名、IP、端口)注册到注册中心, 并向注册中心发送心跳信息来报告自己的健康状态。
  2. 注册中心会存储服务提供者上报的信息,并通过服务提供者发送的心跳来更新服务提供者最后的存活时间,如果超过一段时间没有收到服务提供者上报的心跳信息,则注册中心会认为服务提供者不可用,会将对应的服务提供者从服务列表中剔除。
  3. 服务订阅者会向注册中心订阅自身监听的服务,注册中心会保存服务订阅者的信息,也会向服务订阅者推送服务提供者的信息。
  4. 服务订阅者从注册中心获取到服务提供者的信息时,会直接调用服务提供者的接口来实现远程调用。

服务的注册与发现

服务注册

每个服务实例在启动时都将自己的服务名称、服务IP地址等信息提交到注册中心,注册中心将这些信息维护到实例清单中,这个过程就是服务注册。

有了注册中心之后,当集群规模发生改变、服务实例数量的增加和减少、服务名称发生改变、服务实例部署的IP地址或端口号发生改变,这些情况发生时都会通知注册中心,注册中心会自动修改实例清单中的内容。

服务发现

服务订阅者会从服务的注册中心获取服务提供者的服务列表,或者由服务的注册中心将服务提供者的服务列表变动信息推送给服务订阅者,这个过程叫作服务发现。

比如,订阅者可以在请求一次后就将可用的服务数据缓存到本地,直到注册中心主动将被调用方的服务实例清单变更信息推送过来,再进行本地缓存数据的变更。

服务的健康检查机制

所有的服务实例在注册中心注册成功后,每个服务实例都需要定时发送请求,告诉注册中心自己的健康状态。如果服务实例能够持续发送“心跳”信息,则表示一切正常,服务会被标记为可用的、可发现的。如果注册中心在一段时间内没有收到某个服务实例的“心跳”信息,就会将这个服务实例标记为不可用或不可达的状态,进而从可用的服务列表中剔除该服务实例的信息,在订阅者查询可用的服务实例清单时,该服务实例的信息不会返回给订阅者。

什么是Nacos

Nacos是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos 致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,能快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos的核心特性:
  1. 服务发现和服务健康监测
  2. 动态配置服务
  3. 动态 DNS 服务
  4. 服务及其元数据管理

Nacos环境搭建(单机)

以 MacOS 为例,搭建单机测试环境。

先安装好 JDK,需要 JDK 1.8+ 及其以上版本。

Nacos安装包下载

https://github.com/alibaba/nacos/releases/download/2.2.3/nacos-server-2.2.3.tar.gz

解压安装包
tar -xzvf nacos-server-2.2.3.tar.gz

如果是window系统直接解压即可。

单机模式启动
sh ./startup.sh -m standalone
停止Nacos
sh ./nacos/bin/shutdown.sh
验证是否成功

在浏览器中请求http://ip:8848/nacos,如果可以进入控制台,说明启动成功。

集成Nacos注册中心

创建父项目
  1. 打开开发工具(idea)
  2. 点击create new project
  3. 选择maven
  4. 选择好jdk,点击下一步
  5. 输入名称(比如:aa-springcloud)和项目地址(~/xxx/develop)
  6. pom引入如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>c-springcloud</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.2</version></parent><dependencies><!-- lombok 工具通过在代码编译时期动态的将注解替换为具体的代码,IDEA 需要添加 lombok 插件 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.11</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId></plugin></plugins></build><!-- 项目依赖管理 父项目只是声明依赖,子项目需要写明需要的依赖(可以省略版本信息) --><dependencyManagement><dependencies><!-- spring cloud 依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2022.0.0</version><type>pom</type><scope>import</scope></dependency><!-- spring cloud alibaba 依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2022.0.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>
依赖说明

spring-boot-dependencies:Spring Boot 基础依赖,包括各种 Java 后端框架技术栈、组件、插件等等。

spring-cloud-dependencies:Spring Cloud 相关依赖,比如:Netflix、openfeign、Gateway 等等。

spring-cloud-alibaba-dependencies:Spring Cloud Alibaba 相关依赖,比如:Nacos、Sentinel、RocketMQ 等等。

其他技术、插件依赖等都在父项目中维护版本号,其他子项目继承即可,不需要重复维护版本号。

Spring Cloud Alibaba & Spring Cloud & Spring Boot 之间的依赖关系

Spring Cloud AlibabaSpring CloudSpring Boot
2022.0.0.0Spring Cloud 2022.0.03.0.2
2021.0.4.0Spring Cloud 2021.0.12.6.11
2021.0.1.0Spring Cloud 2021.0.12.6.3
2.2.7.RELEASESpring Cloud Hoxton.SR122.3.12.RELEASE
2021.1Spring Cloud 2020.0.12.4.2
2.2.6.RELEASESpring Cloud Hoxton.SR92.3.2.RELEASE
2.1.4.RELEASESpring Cloud Greenwich.SR62.1.13.RELEASE
2.2.1.RELEASESpring Cloud Hoxton.SR32.2.5.RELEASE
2.2.0.RELEASESpring Cloud Hoxton.RELEASE2.2.X.RELEASE
2.1.2.RELEASESpring Cloud Greenwich2.1.X.RELEASE

spring-boot-maven-plugin(Spring Boot 打包插件,在 Spring Boot 父项目中定义了,只需要 Spring Boot 微服务自行引入)

maven-compiler-plugin(Maven 编译插件,所有项目继承)

用 pluginManagement 和 plugins 分开管理的区别是,pluginManagement 里面的插件是需要项目自行引入的,而 plugins 中的插件是自动继承的

创建子模块
  1. 在父项目名称上右键,依次点击 -> new -> Module…,进入子模块创建界面
  2. 填写模块名称和存储地址,选择jdk等
  3. 子模块pom引入如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.example.cloud</groupId><artifactId>c-springcloud</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>c-service-nacos-client</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!-- nacos --><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- spring boot web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies>
</project>
  1. 创建主入口

在src下创建项目路径比如:com.example.cloud,在此路径下新增一个类,起名为NacosClientApplication。

@EnableDiscoveryClient
@SpringBootApplication
public class NacosClientApplication {public static void main(String[] args) {SpringApplication.run(NacosClientApplication.class, args);}
}
  1. 添加配置文件
    在resource文件夹下创建一个名称为application.yml的配置文件,文件内容如下
server:port: 8000servlet:context-path: /c-service-nacos-client
spring:application:name: c-service-nacos-client # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)cloud:nacos:discovery:server-addr: 127.0.0.1:8848enabled: truenamespace: c3bee016-66ca-4a73-a1f8-af0390e5ce08
  1. 启动项目,验证是否注册成功
    在主启动类中,右键->点击run NacosClientApplication启动项目,打开nacos控制台,在服务管理->服务列表中如果出现了启动的服务,说明注册成功了。
  2. 服务发现代码
    在开发路径下右键点击 -> New -> Package,新建一个名为service的文件夹,在文件夹下创建一个名为NacosClientService的类
@Service
@Slf4j
public class NacosClientService {private final DiscoveryClient discoveryClient;public NacosClientService(DiscoveryClient discoveryClient) {this.discoveryClient = discoveryClient;}/*** 打印Nacos Client中的信息* @return*/public List<ServiceInstance> getNacosClientInfo(String serviceId) {log.info("请求Nacos Client获取服务实例的信息:[{}]", serviceId);return discoveryClient.getInstances(serviceId);}
}

在开发路径下右键点击 -> New -> Package,新建一个名为controller的文件夹,在文件夹下创建一个名为NacosClientController的类

@Slf4j
@RestController
@RequestMapping("/nacos-client")
public class NacosClientController {private final NacosClientService nacosClientService;public NacosClientController(NacosClientService nacosClientService) {this.nacosClientService = nacosClientService;}@GetMapping("service-instance")public List<ServiceInstance> getNacosClientInfo(@RequestParam(defaultValue = "c-service-nacos-client") String serviceId) {log.info("打印nacos client信息:[{}]", serviceId);return nacosClientService.getNacosClientInfo(serviceId);}
}

右键resouce -> New -> Directory,创建一个名为http的路径,然后右键点击http文件夹 -> New -> File,创建一个名为Nacos-client.http的文件

### 查询服务实例信息
GET http://127.0.0.1:8000/c-service-nacos-client/nacos-client/service-instance
Accept: application/json

启动NacosClientApplication项目,进入nacos控制台查看是否注册成功,然后进入nacos-client.http,点击左边的绿色三角请求信息,如果返回如下信息,说明服务实例可以被发现。

[{"serviceId": "c-service-nacos-client","instanceId": null,"host": "192.168.1.235","port": 8000,"secure": false,"metadata": {"nacos.instanceId": null,"nacos.weight": "1.0","nacos.cluster": "DEFAULT","nacos.ephemeral": "true","nacos.healthy": "true","preserved.register.source": "SPRING_CLOUD"},"uri": "http://192.168.1.235:8000","scheme": null}
]  

相关文章:

Nacos环境搭建 -- 服务注册与发现

为什么需要服务治理 在未引入服务治理模块之前&#xff0c;服务之间的通信是服务间直接发起并调用来实现的。只要知道了对应服务的服务名称、IP地址、端口号&#xff0c;就能够发起服务通信。比如A服务的IP地址为192.168.1.100:9000&#xff0c;B服务直接向该IP地址发起请求就…...

Linux了解

简介 Linux是一种自由和开放源代码的类UNIX操作系统&#xff0c;由芬兰的Linus Torvalds于1991年首次发布。Linux最初是作为支持英特尔x86架构的个人电脑的一个自由操作系统&#xff0c;现在已经被移植到更多的计算机硬件平台&#xff0c;如手机、平板电脑、路由器、视频游戏控…...

Keil新版本安装编译器ARMCompiler 5.06

0x00 缘起 我手头的项目在使用最新版本的编译器后&#xff0c;烧录后无法正常运行&#xff0c;故安装5.06&#xff0c;测试后发现程序运行正常&#xff0c;以下为编译器的安装步骤。 0x01 解决方法 1. 下载编译器安装文件&#xff0c;可以去ARM官网下载&#xff0c;也可以使用我…...

【基础训练 || Test-1】

总言 主要内容&#xff1a;一些习题。       文章目录 总言一、选择1、for循环、操作符&#xff08;逗号表达式&#xff09;2、格式化输出&#xff08;转换说明符&#xff09;3、for循环、操作符&#xff08;逗号表达式、赋值和判等&#xff09;4、if语句、操作符&#xff…...

Python读取hbase数据库

1. hbase连接 首先用hbase shell 命令来进入到hbase数据库&#xff0c;然后用list命令来查看hbase下所有表&#xff0c;以其中表“DB_level0”为例&#xff0c;可以看到库名“baotouyiqi”是拼接的&#xff0c;python代码访问时先连接&#xff1a; def hbase_connection(hbase…...

LeetCode41题:缺失的第一个正数(python3)

这道题写的时候完全没有思路&#xff0c;看了很久的题解&#xff0c;才总结出来。 class Solution:def firstMissingPositive(self, nums: List[int]) -> int:nums_set set(nums)n len(nums)for i in range(1, n 1):if i not in nums_set:return ireturn n 1...

C# DataTable 对象操作

实现DataTable按字段进行分类、按列数据汇总、序列化对象数组、所有字段转小写、动态对象数组、数据分页 分类DataTableClassfiy实体&#xff1a; /// <summary>/// 单个分类表/// </summary>public class DataTableClassfiy{/// <summary>/// 分类名称/// &…...

web运行时安全

1.输入验证 对传递的数据的格式、长度、类型&#xff08;前端和后端都要&#xff09;进行校验。 对黑白名单校验&#xff1a;比如前端传递了一个用户名&#xff0c;可以搜索该用户是否在白名单或者黑名单列表。 针对黑名单校验&#xff0c;比如&#xff1a; // 手机号验证…...

FPGA 与 数字电路的关系 - 这篇文章 将 持续 更新 :)

先说几个逻辑&#xff1a;&#xff08;强调一下在这篇文章 输入路数 只有 1个或2个&#xff0c;输出只有1个&#xff0c;N个输入M个输出以后再说&#xff09; 看下面的几个图&#xff1a; 图一&#xff08; 忘了 这是 啥门&#xff0c;不是门吧 &#xff1a;&#xff09;也就…...

18 SpringMVC实战

18 SpringMVC实战 1. 课程介绍2. Spring Task定时任务1. 课程介绍 2. Spring Task定时任务 package com.imooc.reader.task...

Rocky Linux 运维工具 dnf

一、dnf的简介 dnf​是用于在基于RPM包管理系统的包管理工具。用户可以通过 ​yum​来搜索、安装、更新和删除软件包&#xff0c;自动处理依赖关系&#xff0c;它是yum的继任者&#xff0c;旨在提供更快速、更现代化的软件包管理体验。。 二、dnf 的参数说明 序号参数描述1in…...

浅谈 Linux fork 函数

文章目录 前言fork 基本概念代码演示示例1&#xff1a;体会 fork 函数返回值的作用示例2&#xff1a;创建多进程&#xff0c;加深对 fork 函数的理解 前言 本篇介绍 fork 函数。 fork 基本概念 pid_t fork(void) fork 的英文含义是"分叉"&#xff0c;在这里就是 …...

golang 装饰器模式详解

前言 我一直以来对golang的装饰器模式情有独衷&#xff0c;不是因为它酷&#xff0c;而是它带给我了太多的好处。首先我不想说太多的概念&#xff0c;熟记这些概念对我的编程来说一点用处没有。我只知道它给我带来了好处&#xff0c;下面谈谈我的理解。 这种模式可以很轻松地…...

刷题笔记day27-回溯算法2

216. 组合总和 III 这个思路还是&#xff0c;三部曲&#xff1a; 终止条件处理单层节点回溯节点 题中说的是&#xff0c;1到9的数&#xff0c;不能有重复。 k个数&#xff0c;和为n。 那么只要 len(path) k 的时候&#xff0c;判断 n 为0&#xff0c;就可以入切片了。 fun…...

前端架构: 脚手架命令行交互核心实现之inquirer和readline的应用教程

命令行交互核心实现 核心目标&#xff1a;实现命令行行交互&#xff0c;如List命令行的交互呢比命令行的渲难度要更大&#xff0c;因为它涉及的技术点会会更多它涉及以下技术点 键盘输入的一个监听 (这里通过 readline来实现)计算命令行窗口的尺寸清屏光标的移动输出流的静默 …...

【C++初阶】内存管理

目录 一.C语言中的动态内存管理方式 二.C中的内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 3.浅识抛异常 &#xff08;内存申请失败&#xff09; 4.new和delete操作自定义类型 三.new和delete的实现原理 1.内置类型 2.自定义类型 一.C语…...

《PyTorch深度学习实践》第十二讲循环神经网络基础

一、RNN简介 1、RNN网络最大的特点就是可以处理序列特征&#xff0c;就是我们的一组动态特征。比如&#xff0c;我们可以通过将前三天每天的特征&#xff08;是否下雨&#xff0c;是否有太阳等&#xff09;输入到网络&#xff0c;从而来预测第四天的天气。 我们可以看RN…...

蓝桥杯算法题汇总

一.线性表&#xff1a;链式 例题&#xff1a;旋转链表 二.栈&#xff1a; 例题&#xff1a;行星碰撞问题 三.队列 三.数组和矩阵 例题&#xff1a; 四.哈希表 五.二叉树 主要方法是递归 主要考察点是遍历&#xff1a;前序&#xff0c;中序&#xff0c;后序遍历&#xff0c;层…...

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…...

C++设计模式_创建型模式_工厂方法模式

目录 C设计模式_创建型模式_工厂方法模式 一、简单工厂模式 1.1 简单工厂模式引入 1.2 简单工厂模式 1.3 简单工厂模式利弊分析 1.4 简单工厂模式的UML图 二、工厂方法模式 2.1 工厂模式和简单工厂模式比较 2.2 工厂模式代码实现 2.3 工厂模式UML 三、抽象工厂模式 3.1 战斗场景…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...