Nacos介绍与使用

Nacos介绍与使用

文章目录

  • Nacos介绍与使用
    • 一. 什么是Nacos
      • 1 Nacos功能
        • 1.1 配置中心
        • 1.2 注册中心
      • 2.为什么要使用Nacos
    • 二.Nacos 部署安装
      • 1. Nacos 部署方式
      • 2. Nacos 安装
      • 3. 配置数据源
      • 4. 开启控制台授权登录(可选)
    • 三. Nacos配置中心的使用
      • 1. 创建配置信息
      • 2. Spring Boot使用配置中心
        • 1. 添加依赖
        • 2. 设置配置文件
        • 3. 读取配置文件
      • 3.注册中心的使用
        • 1.生产者实现
        • 2.消费者实现
    • 四. 健康检测机制

一. 什么是Nacos

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

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

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

1 Nacos功能

Nacos主要功能有以下两种:

  1. 配置中心
  2. 注册中心
1.1 配置中心

配置中心是一种集中化管理配置的服务。

主要作用如下:

  1. 集中管理配置信息:配置中心将不同服务的配置信息集中进行管理,实现了配置信息的集中管理。
  2. 动态更新配置:通过操作界面或者API进行动态配置更新,消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
  3. 配置信息共享:将配置集中在配置中心中,不同的服务实例可以共享一套配置信息
  4. 配置信息安全:配置中心可以对配置信息提供安全管理、权限管理等管理功能。
  5. 配置快照:支持配置信息版本管理、历史记录等管理功能。
1.2 注册中心

注册中心是微服务架构中的一个重要组件,用于实现不同服务实例的注册与发现

主要作用如下:

  1. 服务注册:服务实例启动时,将自身信息注册到注册中心,包括服务名称、地址、端口等。
  2. 服务发现:消费者向注册中心查询服务,并获取服务实例信息来访问服务。
  3. 服务健康检查:注册中心定期检查服务实例健康状况,过滤不健康实例。
  4. 服务路由:提供服务的路由和负载均衡功能。
  5. 服务监控:统计服务调用次数、时长等,用于监控服务状态
  6. 服务更新:当服务实例信息变更时,向注册中心发送更新信息通知。

通过注册中心,服务提供者和消费者只需与注册中心交互即可,从而实现服务的注册与发现,降低了服务间的耦合度。

2.为什么要使用Nacos

  • 易⽤: 简单的数据模型, 标准的 restfulAPI, 易用的控制台, 丰富的使用文档。
  • 稳定: 99.9% 高可用, 脱胎于历经阿里巴巴 10 年生产验证的内部产品, 支持具有数百万服务的大规模场景, 具备企业级 SLA 的开源产品。
  • 实时: 数据变更毫秒级推送生效; 1w 级, SLA 承诺 1w 实例上下线 1s, 99.9% 推送完成; 10w级, SLA 承诺 1w 实例上下线 3s, 99.9% 推送完成; 100w 级别, SLA 承诺 1w 实例上下线 9s,99.9% 推送完成。
  • 规模: 十万级服务/配置, 百万级连接, 具备强大扩展性。

二.Nacos 部署安装

1. Nacos 部署方式

Nacos有三种部署方式;

  1. 单机模式:将注册中心、配置中心等功能集成在一个进程内,全部部署在一台机器上,适用于测试和单机试用。
  2. 集群模式:多个Nacos服务器实例组成一个集群。这些实例通过相互通信和协调工作,共同提供服务注册、配置管理和服务发现等功能。在集群模式下,所有实例共享相同的数据,数据变更会自动部署到所有的实例中,客户端可以随机选择任意一个实例进行服务的注册与发现。适用于生产环境,确保高可用。
  3. 多集群模式:多集群模式是为了满足在不同的区域或网络中进行部署和扩展的需求,在多集群模式中,可以选择不同的Nacos实例组成多个相互独立的集群,每个集群可以拥有自己独立的配置和注册中心,并可以跨集群进行服务注册与发现。多集群模式适用于分布式系统的多区域部署,并可以使用不同的网络和存储设施。每个集群具有独立的数据和配置,但可以通过自定义的同步机制在集群之间共享数据。

2. Nacos 安装

  1. 环境准备:

    • 安装好 JDK,需要 1.8 及其以上版本
    • 建议: 2核 CPU / 4G 内存 及其以上
    • 建议: 生产环境 3 个节点 及其以上
  2. 安装方式:

    1. 源码安装
    2. 编译压缩包安装(推荐):操作简单

    编译压缩包安装流程:

    1. 下载压缩包: 下载地址 ,下载最新发现版
    2. 解压压缩包:使用unzip nacos-server-$version.zip 或者tar -xvf nacos-server-$version.tar.gz
    3. 进入Nacos运行目录:cd nacos/bin
    4. 启动Nacos服务(单机模式启动):
      • Linux/MacOS: sh startup.sh -m standalone
      • Windows:cmd startup.cmd -m standalone

    启动成功后可以使用:localhost:8848/nacos进行访问Nacos的控制台,如下图所示:

    image-20231111000158601

集群部署说明:https://nacos.io/zh-cn/docs/v2/guide/admin/cluster-mode-quick-start.html

3. 配置数据源

Nacos单机模式下默认使用的数据源是内置的嵌入式数据库Derby作为数据库,但是Derby不适合承载生产环境大规模部署,因为有以下限制:

  1. 数据存储容量只有2GB;
  2. 不支持集群模式下的高可用复制;
  3. 性能和并发能力有限制

因此在生产环境中使用单机模式时,可以使用外置数据库作为数据存储,例如MySQL。

在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力,具体的操作步骤:

  1. 安装MySQL,版本要求:5.6.5+;

  2. 初始化MySQL数据库,数据库初始化文件:sql语句源文件;

  3. 修改Nacos安装目录中conf/application.properties文件,增加支持MySQL数据源配置,配置如下:

    spring.datasource.platform=mysql
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=nacos
    db.password.0=nacos
    

    参考文档:application.properties配置文件

    再以单机模式启动nacos,nacos所有写嵌入式数据库的数据都写到了mysql

    最后,重新启动Nacos服务。

对于集群模式下的部署可参考官方文档:集群模式下运行Nacos

4. 开启控制台授权登录(可选)

首先找到Nacos安装目录中conf/application.properties文件,修改以下内容:

nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=${自定义,保证所有节点一致}
nacos.core.auth.server.identity.key=${自定义,保证所有节点一致}
nacos.core.auth.server.identity.value=${自定义,保证所有节点一致}

注意,文档中的默认值SecretKey012345678901234567890123456789012345678901234567890123456789VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=为公开默认值,可用于临时测试,实际使用时请务必更换为自定义的其他有效值。

至此,我们Nacos集群环境就搭建成功了,接下来就是使用Nacos服务的两个核心功能了。

三. Nacos配置中心的使用

1. 创建配置信息

image-20231113182408418

参数说明:

  1. 命名空间:Nacos 基于Namespace 帮助用户逻辑隔离多个命名空间,这可以帮助用户更好的管理测试、预发、生产等多环境服务和配置,让每个环境的同一个配置(如数据库数据源)可以定义不同的值。
  2. Data ID:配置的唯一标识,用于查找配置文件。
  3. Group:配置分组,用于设置小组信息。

2. Spring Boot使用配置中心

实现步骤:

  1. 添加nacos-config依赖。
  2. 在配置文件(application.properties)中设置Nacos相关信息。
  3. 使用@Value@RefreshScope实现配置的读取和自动更新。
1. 添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2. 设置配置文件
# Nacos认证信息
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
spring.cloud.nacos.config.contextPath=/nacos
# 设置配置中心服务端地址
spring.cloud.nacos.config.server-addr=localhost:8848
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
# spring.cloud.nacos.config.namespace=
spring.config.import=nacos:nacos-config-example
# 配置文件类型
spring.cloud.nacos.config.file-extension=properties
3. 读取配置文件
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RefreshScope
public class TestController {@Value("${myconfig}")private String myconfig;@RequestMapping("/getconfig")public String getMyconfig(){return  myconfig;}
}	

3.注册中心的使用

注册中心的交互流程:

image-20231121194329602

注册中心通常有两个角色:

  1. 服务提供者(生产者):对外提供服务的微服务应用。它会把自身的服务注册到服务中心,以供消费者发现和调用。
  2. 服务调用者(消费者):调用其他微服务的应用程序。它会向注册中心订阅自己需要的服务,并基于服务提供者信息发起远程调用。
1.生产者实现

生产者实现有以下3步:

  1. 添加nacos-discovery依赖
  2. 配置nacos服务端信息
  3. 编写调用接口
  1. 添加依赖

    <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>${latest.version}</version>
    </dependency>
    
  2. 设置服务端信息

    spring:application:name: nacos-discovery-demo #nacos服务名cloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacos
  3. 编写调用接口

    @RestController
    @RequestMapping("/user")
    public class UserController {   @RequestMapping("/getnamebyid")public String getNameById(Integer id) throws InterruptedException {return "name: "+ id;}
    }
    
2.消费者实现

实现过程:消费者首先调用生产者的HTTP接口,需要引入Spring Cloud OpenFeign进行HTTP调用,其次为了实现负载均衡,我们还需要引入客户端负载均衡器:Spring Cloud LoadBalancer

具体的OpenFeignLoadBalancer的功能,将会在后续文章中进行详细介绍。

因此消费者实现有以下步骤:

  1. 引入依赖(Nacos注册中心、OpenFeign、Spring Cloud LoadBalancer)
  2. 配置Nacos服务端信息
  3. 在项目中开启OpenFeign
  4. 编写OpenFeign调用代码
  5. 通过OpenFeign调用生产者
  1. 引入依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 配置Nacos服务端信息

    spring:application:name: nacos-consumer-democloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 消费者(不需要注册到nacos中)
    
  3. 在项目中开启OpenFeign

    在启动类文件中添加@EnableFeignClients注解即可

  4. 编写OpenFeign调用代码

    @Service
    @FeignClient("nacos-discovery-demo") // 表示调用 nacos 中的 nacos-discovery-demo 服务
    public interface UserService {@RequestMapping("/user/getnamebyid") // 调用生产者的"/user/getnamebyid"接口public String getNameById(@RequestParam("id") int id);}
    
  5. 通过OpenFeign调用生产者

    @RestController
    public class BusinessController {@Autowiredprivate UserService userService;@RequestMapping("/getnamebyid")public String getNameById(Integer id){return userService.getNameById(id);}}
    

启动服务后,我们就可以在Nacos控制台看到生产者的服务

image-20231121201201077

进入详情页面后可以看到服务的相关信息

image-20231121201237890

在服务详情页面中,可以看到有许多的参数信息

**分组:**注册服务的所在的组名,默认是DEFAULT_GROUP

**保护阈值:**健康节点要求的最小百分比。用于在服务出现不健康实例时,阻止流量过度向少量健康实例中,保护服务的整体可用性。保护阈值的范围是0到1之间的浮点数,默认为0。当集群中健康的实例占比小于设置的保护阈值时,就会触发阈值保护功能。触发阈值保护后,Nacos会将全部实例(健康实例+不健康实例)全部返回给调用者,虽然损失了一部分流量,但是保证了集群中剩余的健康实例能正常工作。

**服务路由类型:**由于实现不同的路由需求,常见的路由类型有以下两种:

  • **none:**默认路由,基于权重的轮询负载均衡路由策略。
  • **label:**标签路由,相同标签的实例会被聚合为一个集群,不同标签则实现流量隔离。

**临时实例:**Nacos会将服务分为临时实例和永久实例,临时实例的生命周期和服务运行周期相同,服务停止运行,Nacos会将临时实例删除;而永久实例即使程序运行停止,也会在Nacos中。

  • 临时实例(Temporary instances):是指注册到注册中心的服务实例,其注册信息在实例下线或不可用时会自动删除。如果服务实例下线、断开连接或主动注销,Nacos会自动从注册表中删除实例的信息。临时实例适用于临时性的服务实例。
  • 永久实例(Permanent Instance):是指注册到注册中心的服务实例,其注册信息一直保存在Nacos服务器上,直到主动注销或被删除。意味着当服务下线或不可用时,它的注册信息仍保留在Nacos上,直到显示取消注册。永久实例适用于需要长期存在的服务。

对于永久实例实现,通过在配置文件中ephemeral: true实现(yaml文件中于nacos.discover.username同级)

**权重:**用于实现负载均衡,取值范围为0到10000,数值越大,权重越大,负载均衡分配的概率就越高。设置0表示下线。

四. 健康检测机制

Nacos中健康检测机制是用来检测服务健康状态的,只要健康的节点才能被服务端调用,这样程序才能正常的、稳定的运行。

在Nacos中有两种健康检测机制:

  1. 客户端主动上报机制。
  2. 服务端反向探测机制。
image-20231121210954495

如何设置健康检测机制:

在Nacos中健康检测机制不能主动设置,但健康检测机制是和Nacos的服务实例类型强相关的。在Nacos中的两种服务实例分别对应不同的健康检测机制:

  1. 临时实例(也可以叫做非持久化实例):对应客户端主动上报机制。
  2. 永久实例(也可以叫做持久化实例):对应服务端反向探测机制。

客户端主动上报机制

临时实例每隔5秒会主动上报一次自己的健康状况,发送的数据包叫做心跳包,发送心跳包的机制叫做心跳机制。如果心跳包的间隔时间超过了15秒,那么Nacos服务器端就会将此服务实例标记为非健康实例,如果超过了30秒,那么Nacos服务器端将会把此服务实例从服务列表中删除掉。

服务端反向探测机制

永久实例使用的是服务器端反向探测机制,它的探测周期是2000毫秒+随机数(5000毫秒以内),如果检测异常会将此服务实例标记为非健康实例,但不会把实例删除。

Nacos服务器反向探测目前内置了3中探测协议:HTTP探测、TCP探测、MySQL探测。默认使用的是TCP探测。

关于Nacos更多的使用可以参考Nacos官方手册:https://nacos.io/zh-cn/docs/architecture.html

以上是博主对Nacos的介绍,制作不易,看完留下你的一键三连吧!
的间隔时间超过了15秒,那么Nacos服务器端就会将此服务实例标记为非健康实例,如果超过了30秒,那么Nacos服务器端将会把此服务实例从服务列表中删除掉。

服务端反向探测机制

永久实例使用的是服务器端反向探测机制,它的探测周期是2000毫秒+随机数(5000毫秒以内),如果检测异常会将此服务实例标记为非健康实例,但不会把实例删除。

Nacos服务器反向探测目前内置了3中探测协议:HTTP探测、TCP探测、MySQL探测。默认使用的是TCP探测。

关于Nacos更多的使用可以参考Nacos官方手册:https://nacos.io/zh-cn/docs/architecture.html

以上是博主对Nacos的介绍,制作不易,看完留下你的一键三连吧!

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

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

相关文章

2023年【T电梯修理】考试题及T电梯修理考试报名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 T电梯修理考试题是安全生产模拟考试一点通总题库中生成的一套T电梯修理考试报名&#xff0c;安全生产模拟考试一点通上T电梯修理作业手机同步练习。2023年【T电梯修理】考试题及T电梯修理考试报名 1、【多选题】GB/T1…

python日志输出和命令行参数解析示例

代码包含日志终端输出、日志文件输出和命令行参数解析示例 主要功能&#xff0c;根据命令行参数复制对应比例的文件到指定的文件夹中&#xff0c;并输出相应日志 import os import random import shutil import logging import argparse def copy_random_files(input_folder, …

红队攻防之Goby反杀

若结局非我所愿&#xff0c;那就在尘埃落定前奋力一搏。 本文首发于先知社区&#xff0c;原创作者即是本人 一、弹xss 为了方便&#xff0c;本次直接使用 PhpStudy 进行建站&#xff0c;开启的web服务要为MySQLNginx&#xff0c;这里的 PhpStudy 地址为 http://x.x.x.x&…

线程池的异常处理机制

起因 一次开发过程中&#xff0c;送审之后向三方OA系统推送代办&#xff0c;其中由于优化的原因使用到线程池 ExecutorService todoMessageAsyncThread ThreadPoolManager.getThreadPool("todoMessageAsyncThreadPool");todoMessageAsyncThread.submit(() -> {…

【Leetcode Sheet】Weekly Practice 16

Leetcode Test 1334 阈值距离内邻居最少的城市(11.14) 有 n 个城市&#xff0c;按从 0 到 n-1 编号。给你一个边数组 edges&#xff0c;其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边&#xff0c;距离阈值是一个整数 distanceThreshold。…

Hibernate 一级缓存,二级缓存,查询缓存

概念&#xff1a; 1.什么是缓存呢&#xff1f; 缓存&#xff1a;是计算机领域的概念&#xff0c;它介于应用程序和永久性数据存储源之间。 缓存&#xff1a;一般人的理解是在内存中的一块空间&#xff0c;可以将二级缓存配置到硬盘。用白话来说&#xff0c;就是一个存储数据的…

Web前端—移动Web第三天(移动Web基础、rem、less、综合案例—极速问诊)

版本说明 当前版本号[20231120]。 版本修改说明20231120初版 目录 文章目录 版本说明目录移动 Web 第三天01-移动 Web 基础谷歌模拟器屏幕分辨率视口二倍图适配方案 02-rem简介媒体查询rem 布局flexible.jsrem 移动适配 03-less注释运算嵌套变量导入导出禁止导出 04-综合案例…

GNSS技术在灾害监测与应急响应中的关键作用

全球导航卫星系统&#xff08;GNSS&#xff09;技术在灾害监测与应急响应领域发挥着重要作用&#xff0c;为预防、监测和应对自然灾害提供了关键数据支持。本文将深入探讨GNSS技术在灾害监测与应急响应中的作用&#xff0c;并分析其对提高应对灾害能力的重要性。 一、GNSS在灾害…

android报错

&#xff08;gradle版本&#xff1a;7.5-all.zip; gradle插件&#xff1a;7.4.2&#xff1b;java:11) 报错1&#xff1a; java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode 2023-11-20 19:39:39.207 22390-22390 AndroidRuntime com…

InnoDB 的一次更新事务是怎么实现的?

大体流程&#xff1a; 步骤: 1.加载数据到缓存中&#xff08;Buffer Pool&#xff09;&#xff1a; 在进行数据更新时&#xff0c;InnoDB首先会在缓冲池&#xff08;Buffer Pool&#xff09;中查找该记录是否已经在内存中。如果记录不在内存中&#xff0c;会将需要更新的数据…

2021年03月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 小猫在沙漠中旅行好不容易找到了一杯水,初始位置如下图所示,下面哪个程序可以帮助它成功喝到水? A: B: C: D:

基于像素特征的kmeas聚类的图像分割方案

kmeans聚类代码 将像素进行聚类&#xff0c;得到每个像素的聚类标签&#xff0c;默认聚类簇数为3 def seg_kmeans(img,clusters3):img_flatimg.reshape((-1,3))# print(img_flat.shape)img_flatnp.float32(img_flat)criteria(cv.TERM_CRITERIA_MAX_ITERcv.TERM_CRITERIA_EPS,2…

stack和queue简单实现(容器适配器)

容器适配器 stack介绍stack模拟实现queue 介绍queue模拟实现deque stack介绍 stack模拟实现 以前我们实现stack&#xff0c;需要像list,vector一样手动创建成员函数&#xff0c;成员变量。但是stack作为容器适配器&#xff0c;我们有更简单的方法来实现它。 可以利用模板的强大…

练习六-使用Questasim来用verilog使用function函数

[TOC](使用Questasim来用verilog使用function函数 1&#xff0c;verilog中使用函数function2&#xff0c;RTL代码3&#xff0c;测试代码4&#xff0c;输出波形 1&#xff0c;verilog中使用函数function 目的&#xff1a; &#xff08;1&#xff09;了解函数的定义和在模块设计中…

【面试】测试/测开(未完成版)

1. 黑盒测试方法 黑盒测试&#xff1a;关注的是软件功能的实现&#xff0c;关注功能实现是否满足需求&#xff0c;测试对象是基于需求规格说明书。 1&#xff09;等价类&#xff1a;有效等价类、无效等价类 2&#xff09;边界值 3&#xff09;因果图&#xff1a;不同的原因对应…

日常办公:批处理编写Word邮件合并获取图片全路径

大家在使用Word邮件合并这个功能&#xff0c;比如制作席卡、贺卡、准考证、员工档案、成绩单、邀请函、名片等等&#xff0c;那就需要对图片路径进行转换处理&#xff0c;此脚本就是直接将图片的路径提取出来&#xff0c;并把内容放到txt格式的文本文档里&#xff0c;打开Excel…

AcWing 4. 多重背包问题 I 学习笔记

有 N&#xfffd; 种物品和一个容量是 V&#xfffd; 的背包。 第 i&#xfffd; 种物品最多有 si&#xfffd;&#xfffd; 件&#xff0c;每件体积是 vi&#xfffd;&#xfffd;&#xff0c;价值是 wi&#xfffd;&#xfffd;。 求解将哪些物品装入背包&#xff0c;可使物…

JudgeOpen整理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…

九韵和声 饕餮盛宴丨音乐和声与校友情谊的完美交融

“九韻和聲”音樂會於11月19日晚上在深圳大劇院盛大舉行。來自各高校深圳校友會的逾千名同學們歡聚一堂&#xff0c;共同慶祝自己的合唱音樂會。 首次舉辦合唱音樂會 “九韵和声”音乐会由深圳市西安交通大学校友会牵头发起、主办&#xff0c;与深圳市清华大学校友会、深圳市浙…

基于非链式(数组)结点结构的二叉树的前(先)序输入创建以及遍历

点击链接返回标题->基于非链式(数组)结点结构的二叉树的层序、先序、中序、后序输入创建以及层序、先序、中序、后序输出-CSDN博客 我们采用递归的思想&#xff0c;不断去找空结点&#xff08;值为-1的结点&#xff09;&#xff0c;在找空结点这个过程中&#xff0c;将输入的…