- 微服务从小白到专家:Spring Cloud和Kubernetes实战
- 姚秋辰 张昕 卿睿
- 3339字
- 2025-02-16 16:46:59
6.4 Nacos实战
6.4.1 Nacos与Spring Cloud的集成
在开始之前,我们需要将Nacos依赖项引入Spring Cloud项目中。引入Nacos依赖项的方式有两种,一种是在pom.xml文件中引入org.springframework.cloud:spring-cloud-starter-alibaba-nacos-discovery(config)依赖项,另一种是引入com.alibaba.cloud:spring-cloud-alibaba-dependencies依赖项。如果读者需要在项目中使用Spring cloud Alibaba的其他组件,建议采用官方推荐的版本兼容方案,Spring Cloud与Nacos的版本依赖关系如图6-6所示。

图6-6 Spring Cloud与Nacos的版本依赖关系
读者可以根据项目需要选择对应的版本。笔者在演示项目中均采用spring-cloud-starter-alibaba-nacos*的方式引入依赖项。
6.4.2 Nacos控制台
我们可以通过浏览器打开Nacos的控制台(控制台地址:http://localhost:8848/nacos)。在登录对话框输入默认的admin账号、对应的用户名和密码(均为nacos)后进入管理界面,Nacos控制台主界面如图6-7所示。

图6-7 Nacos控制台主界面
在本章中,我们重点学习图6-7左侧导航栏的“配置管理”和“服务管理”两个功能,关于这两个功能的详细介绍请参见6.4.3节和6.4.4节。下面我们对左侧菜单栏中的菜单项做一个简单介绍。
权限控制主要用于管理Nacos的用户和用户的权限,Nacos权限控制界面如图6-8所示。

图6-8 Nacos权限控制界面
权限控制有如下3个主要功能:
(1)在“用户列表”界面中,admin可以维护Nacos的用户(新建、修改密码、删除用户)。
(2)在“角色管理”界面中,可以将用户与角色进行绑定。
(3)在“权限管理”界面中,可以对角色进行赋权。
通过以上功能,可以得知Nacos的权限体系是基于角色构建的,接下来,我们使用管理界面来创建一个新用户,并测试其权限体系。
首先,我们在Nacos中创建一个名为readuser的用户,并设置密码,如图6-9所示。

图6-9 Nacos创建用户
然后,我们创建一个新的角色名,并将该角色的权限设置为读写权限,如图6-10所示。

图6-10 Nacos创建角色
最后,我们将创建好的用户账号与角色进行绑定,如图6-11所示。

图6-11 将用户与角色进行绑定
我们退出当前处于登录状态的admin用户,用新创建的readuser登录,可以观察到控制台的菜单项发生了变化,即左侧的权限管理菜单消失了。非admin用户管理界面如图6-12所示。

图6-12 非admin用户管理界面
下面我们针对图6-12中的“命名空间”和“集群管理”两个菜单项做简单介绍。
(1)命名空间,顾名思义,即维护Name Space的界面,命名空间界面如图6-13所示。

图6-13 命名空间界面
(2)集群管理,展示当前Nacos服务器的运行状态,集群管理界面如图6-14所示。

图6-14 集群管理界面
6.4.3 Nacos实现配置管理
在本节中,我们将在Nacos中添加新的配置项,将微服务程序连接到Nacos服务器并读取配置项。
配置项的添加操作可以通过“新建配置”页面来完成,在该页面添加所需配置项,并单击“发布”按钮完成添加,Nacos创建新配置如图6-15所示。

图6-15 Nacos创建新配置
如6.2.2节所述,Nacos Config的概念与Spring Environment和PropertySource具有一致的代码层抽象逻辑。当Spring Boot应用启动时,应用程序会主动从Nacos读取配置项并加载到Spring容器中。Nacos Config实现了配置项的环境隔离功能,当Spring Boot应用被部署到不同环境(开发、测试或生产环境)中时,我们可以通过管理界面为不同的环境设置不同的配置项,尽可能地减少代码对环境的依赖,从而增强配置对代码的透明性和可迁移性。
实现Nacos配置管理功能分为以下几步:
(1)添加依赖项
按照3.1节的步骤创建Spring Boot项目并引入正确的Spring Cloud和Alibaba Spring Cloud版本依赖,再额外引入nacos-config-starter依赖项到pom.xml文件中,nacos-config-starter依赖项的具体代码如下:

(2)约定命名规则
Nacos的DataID命名规则为:${prefix}-${spring.profile.active}.${file-extension},这些占位符的具体含义如下:
• prefix默认为spring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来指定一个不同的值。
• spring.profile.active即当前运行的Spring Boot应用的profile(通常表示所在环境),当spring.profile.active为空时(即默认),命名规则中对应的连接符“-”也可以省去,变成prefix.{file-extension}。
• file-exetension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置。目前只支持properties和YAML类型。
在本例中,DataID的值为broadview-demo.properties,为了与DataID相匹配,我们需要对Spring Boot示例程序的参数做相应的修改,同时也需要为应用指定Nacos Server的连接地址,以上两项配置均需在bootstrap.properties中添加。笔者不建议在application.properties中添加配置中心地址,因为bootstrap.properties的加载优先级高于application.properties,为了确保配置项初始化的正确顺序,相关配置需要添加在bootstrap.properties文件中,配置项的代码如下:

(3)运行项目
运行Spring Boot项目的main()方法,如果项目启动成功,将看到如图6-16所示的项目启动日志。

图6-16 项目启动日志
(4)引入外部配置项
我们在程序中添加一个简单的Controller类,读取Nacos中的配置项并返回,代码如下:


在上述代码中,我们通过@Value注解将外部配置注入Spring Boot应用的上下文中,为了支持运行期属性的动态刷新(在不重启应用的情况下刷新配置项),我们在类名上添加了注解@RefreshScope。
打开浏览器,输入访问地址http://localhost:8080/nacos/config,浏览器打印结果如图6-17所示,证明配置项已被正确加载。

图6-17 浏览器打印结果
(5)配置刷新
进入Nacos配置中心修改title和name这两项配置的值,修改配置界面如图6-18所示。

图6-18 修改配置界面
修改完成后,查看Spring Boot服务日志,会看到配置项刷新的内容,如图6-19所示。

图6-19 Spring Boot服务日志中配置项刷新的内容
刷新步骤(4)中的浏览器界面,查看页面变化,配置刷新后的界面如图6-20所示。

图6-20 配置刷新后的界面
Nacos还可以从profile层面做配置隔离(环境隔离),进入Nacos配置中心创建新的DataID并命名为broadview-demo-qa.properties,profile的配置如图6-21所示。

图6-21 profile的配置
重新启动Spring Boot应用(无代码修改),在启动脚本中添加如下启动参数:

该参数表示当前微服务的profile为qa,因此,服务启动阶段将从配置中心读取profile=qa的配置文件,前述实验中使用默认的profile,即没有设置此启动参数。我们刷新页面后看到如图6-22所示的访问QA profile的界面。

图6-22 访问QA profile的界面
目前所有的演示均基于Nacos的默认设置,在默认配置下我们采用standalone模式启动Nacos服务器,配置项的持久化方案也采用默认的存储方案。为了更进一步了解Nacos的特性,接下来我们将以cluster集群模式启动Nacos,并将存储方案改为MySQL。
首先需要安装MySQL,具体安装步骤请参照3.4.1.2节。在MySQL安装完成之后,我们通过以下步骤在MySQL中创建Nacos的相关数据库表:
(1)用root账号连接MySQL,创建Nacos要使用的database命名为nacos,SQL语句如下:

(2)切换到nacos数据库下,SQL语句如下:

(3)创建Nacos所需的数据库表,建表语句所在的文件位于Nacos目录下的Conf文件夹下,以下命令中的NACOS_PATH指Nacos编译成功的目录:

然后,可以运行show tables命令查看数据库表是否被正确创建。
(4)修改Nacos配置文件,使用MySQL存储配置项。Nacos配置文件的路径是{NACOS_PATH}/conf/application.properties,具体代码如下:

(5)创建{NACOS_PATH}/conf/cluster.conf(集群配置文件)。
该目录下有Nacos提供的cluster.conf.example文件作为参考,我们在cluster.conf中仅添加一个本地地址即可(以笔者为例,将本地IP地址192.168.1.3添加到该文件中)。
通过“startup.sh -m cluster”命令重新启动Nacos,打开配置中心页面,由于Nacos底层存储方案发生了变更,所以此前创建的DataID都不存在了,我们需要重新创建这些配置项,在集群模式下增加配置,如图6-23所示。

图6-23 在集群模式下增加配置
配置增加完毕后,再次访问Spring Boot应用的Controller接口,应用可以正确获取配置项,集群模式下的配置项获取如图6-24所示。

图6-24 集群模式下的配置项获取
检查MySQL中的数据,可以看到新添加的配置项,MySQL的配置数据如图6-25所示。

图6-25 MySQL的配置数据
6.4.4 Nacos实现服务注册与服务发现
为了实现服务注册与服务发现,我们需要创建两个独立的Spring Boot应用,分别作为服务提供者和服务消费者。由于篇幅原因,本节只对主要步骤进行介绍,完整源码请参考本书的GitHub主页。
服务提供者的创建步骤如下:
(1)引入Nacos依赖,代码如下:

(2)修改bootstrap.properties文件,指定当前应用的应用名和Nacos的连接地址,具体代码如下:

(3)创建Application启动类,并在类上添加@EnableDiscoveryClient注解(此注解来自Spring Cloud)。
(4)创建一个名为ServiceController的测试类,具体代码如下:

(5)启动应用,通过Nacos控制台的“服务管理”的“服务列表”可以查看已注册的服务名,服务注册详情如图6-26所示。


图6-26 服务注册详情
服务消费者的创建步骤如下:
(1)引入与服务提供者相同的依赖项。
(2)修改bootstrap.properties,添加以下项目:

(3)创建启动类Application并添加EnableDiscoveryClient注释(此注释来自Spring cloud),在启动类中声明一个具有负载均衡能力的RestTemplate类,我们可以通过RestTemplate类发起远程REST接口的调用请求。Application启动类的具体代码如下:

(4)创建一个测试方法,在方法中向服务提供者发起一个远程调用,具体代码如下:


(5)启动应用,查看Nacos控制台的“服务管理”的“服务列表”,服务注册详情如图6-27所示。

图6-27 服务注册详情
打开浏览器,访问服务消费者接口(笔者本地访问路径为http://localhost:10001/consumer/hello),可以看到如图6-28所示的远程方法调用结果。

图6-28 远程方法调用结果
本章中,笔者通过示例程序演示了Nacos的基础功能,在实际工作中,特别是在大规模集群下,无论是服务注册还是配置管理都面临着非常大的技术挑战。例如,跨中心的数据一致性问题、变更推送的延迟问题,以及Nacos集群本身的容灾能力等。本章介绍的Nacos知识点只是抛砖引玉,还请读者在工作和学习中继续探索更大更广阔的Nacos应用场景。