- 微服务从小白到专家:Spring Cloud和Kubernetes实战
- 姚秋辰 张昕 卿睿
- 3339字
- 2021-10-29 12:24:41
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所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/263-01.jpg?sign=1739022354-axRykvPGH0wTGZERBeJ0KNvhZz1atuDi-0-55cbff103c5f66e85953ba5f5ab13fde)
图6-6 Spring Cloud与Nacos的版本依赖关系
读者可以根据项目需要选择对应的版本。笔者在演示项目中均采用spring-cloud-starter-alibaba-nacos*的方式引入依赖项。
6.4.2 Nacos控制台
我们可以通过浏览器打开Nacos的控制台(控制台地址:http://localhost:8848/nacos)。在登录对话框输入默认的admin账号、对应的用户名和密码(均为nacos)后进入管理界面,Nacos控制台主界面如图6-7所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/264-01.jpg?sign=1739022354-YDlG1opdrrjxnmr4C2lZcN853hrFvAqO-0-93e3652b4a879cf5e84bbace68e2f778)
图6-7 Nacos控制台主界面
在本章中,我们重点学习图6-7左侧导航栏的“配置管理”和“服务管理”两个功能,关于这两个功能的详细介绍请参见6.4.3节和6.4.4节。下面我们对左侧菜单栏中的菜单项做一个简单介绍。
权限控制主要用于管理Nacos的用户和用户的权限,Nacos权限控制界面如图6-8所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/264-02.jpg?sign=1739022354-hFAKc1P7TuviWUQgYKWpZh4K5WPI8uMM-0-856ddf9bd7b4542b07f9a12594deacf3)
图6-8 Nacos权限控制界面
权限控制有如下3个主要功能:
(1)在“用户列表”界面中,admin可以维护Nacos的用户(新建、修改密码、删除用户)。
(2)在“角色管理”界面中,可以将用户与角色进行绑定。
(3)在“权限管理”界面中,可以对角色进行赋权。
通过以上功能,可以得知Nacos的权限体系是基于角色构建的,接下来,我们使用管理界面来创建一个新用户,并测试其权限体系。
首先,我们在Nacos中创建一个名为readuser的用户,并设置密码,如图6-9所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/265-01.jpg?sign=1739022354-8uu78G1011RieCOqlXaDuVBtQjzKZW3O-0-f05911e8ab35a6ecce55f1e4e261f2fd)
图6-9 Nacos创建用户
然后,我们创建一个新的角色名,并将该角色的权限设置为读写权限,如图6-10所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/265-02.jpg?sign=1739022354-4PriqepfFFwIF1vE3LJ5q9wJZphPeicj-0-401384f02e75c7cc5683ee6afb3f362d)
图6-10 Nacos创建角色
最后,我们将创建好的用户账号与角色进行绑定,如图6-11所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/265-03.jpg?sign=1739022354-4iWbfDF5rbA6P2km4WcUqnVhv2mgefZQ-0-7b185fb0341ab772d3133a24cbe7da5d)
图6-11 将用户与角色进行绑定
我们退出当前处于登录状态的admin用户,用新创建的readuser登录,可以观察到控制台的菜单项发生了变化,即左侧的权限管理菜单消失了。非admin用户管理界面如图6-12所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/266-01.jpg?sign=1739022354-7DocPNCZkeKFCoMy38FJyjRcOhe95x4o-0-856eb3d2075d878546f8f46bbdad5bcf)
图6-12 非admin用户管理界面
下面我们针对图6-12中的“命名空间”和“集群管理”两个菜单项做简单介绍。
(1)命名空间,顾名思义,即维护Name Space的界面,命名空间界面如图6-13所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/266-02.jpg?sign=1739022354-H6B2xWiufGRX4kSf67i8SHG5cfBLAytU-0-e26b3538a1dc3e17fad304649b9aad08)
图6-13 命名空间界面
(2)集群管理,展示当前Nacos服务器的运行状态,集群管理界面如图6-14所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/266-03.jpg?sign=1739022354-VqSjKvOuKBsuZ9VAiRHQ3aR9C5S5XwmN-0-766835ee737468f3a893d08c17ad2235)
图6-14 集群管理界面
6.4.3 Nacos实现配置管理
在本节中,我们将在Nacos中添加新的配置项,将微服务程序连接到Nacos服务器并读取配置项。
配置项的添加操作可以通过“新建配置”页面来完成,在该页面添加所需配置项,并单击“发布”按钮完成添加,Nacos创建新配置如图6-15所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/267-01.jpg?sign=1739022354-Fi9ZRYjnfK0uedOzMtwKx6SM8q28HaNq-0-cc29c6ddcf5ad88e91181bf5f775fe1c)
图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依赖项的具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/267-1.jpg?sign=1739022354-aHWewNtksTYCOL09V4PJXrf7zipJCSz7-0-cd156524fdc13fc8360d1cf6dba6d1d4)
(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文件中,配置项的代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/268-1.jpg?sign=1739022354-ZTKjrOkS1qBrGpu3dDPIEfe35C5hvNH9-0-f496cc06e2e74ee2ffbadbf5e465581a)
(3)运行项目
运行Spring Boot项目的main()方法,如果项目启动成功,将看到如图6-16所示的项目启动日志。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/268-02.jpg?sign=1739022354-eoPKtDo1uA62F6ne9ozbR4nkLhkO24IN-0-07b5f59be677645ee74264fd636de2f4)
图6-16 项目启动日志
(4)引入外部配置项
我们在程序中添加一个简单的Controller类,读取Nacos中的配置项并返回,代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/268-2.jpg?sign=1739022354-RE4hDI8JQtXmR7oXxf6mDejWtUQrg55D-0-dcc5bcb2b8ed5a871b0550722e0ef5fb)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/269-1.jpg?sign=1739022354-5bV2JfmfGGyxSRtQGuLKhNZYK4JdP8Sc-0-d9068cb019ceaacab7a4e82de682cb7a)
在上述代码中,我们通过@Value注解将外部配置注入Spring Boot应用的上下文中,为了支持运行期属性的动态刷新(在不重启应用的情况下刷新配置项),我们在类名上添加了注解@RefreshScope。
打开浏览器,输入访问地址http://localhost:8080/nacos/config,浏览器打印结果如图6-17所示,证明配置项已被正确加载。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/269-01.jpg?sign=1739022354-MLyWNNwm6YOowUyuc0tI3DbUk6rThvFK-0-9df061dac79838a4cf5bdda17abfb236)
图6-17 浏览器打印结果
(5)配置刷新
进入Nacos配置中心修改title和name这两项配置的值,修改配置界面如图6-18所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/269-02.jpg?sign=1739022354-y9YYH9qRWBgYBeANwRC0FO6b2JLeMGxc-0-7566d987a631e7cab80aca8c56fba71b)
图6-18 修改配置界面
修改完成后,查看Spring Boot服务日志,会看到配置项刷新的内容,如图6-19所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/270-01.jpg?sign=1739022354-IvrbmnoRbt3bFl8kEMnHpfMkNDLYgyl3-0-60a9aecf053a50757696458c942475ed)
图6-19 Spring Boot服务日志中配置项刷新的内容
刷新步骤(4)中的浏览器界面,查看页面变化,配置刷新后的界面如图6-20所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/270-02.jpg?sign=1739022354-JOB8g0ikH4DlujFbbj0f9UuvimbIkB0F-0-78abe06db85919bc9b6b8651b63b6886)
图6-20 配置刷新后的界面
Nacos还可以从profile层面做配置隔离(环境隔离),进入Nacos配置中心创建新的DataID并命名为broadview-demo-qa.properties,profile的配置如图6-21所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/270-03.jpg?sign=1739022354-nhknSzVsssNw8GEHRk3jgdfk23rMQTLB-0-700ca11c65b5d263bded3a9507a712ec)
图6-21 profile的配置
重新启动Spring Boot应用(无代码修改),在启动脚本中添加如下启动参数:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/270-1.jpg?sign=1739022354-qhu5OJFOXOHeU6kPeUW1XJeua7luU0TQ-0-7747bc1f1c90bde871558fa7bfb7caf9)
该参数表示当前微服务的profile为qa,因此,服务启动阶段将从配置中心读取profile=qa的配置文件,前述实验中使用默认的profile,即没有设置此启动参数。我们刷新页面后看到如图6-22所示的访问QA profile的界面。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/270-04.jpg?sign=1739022354-x4X3oqBxzFFMrBUIlSR0fakaIncSmSRX-0-a0d6c1004941c820c4dc4ccd26446009)
图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语句如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/271-1.jpg?sign=1739022354-1uGOqi2fUZPACbBxnk32CZqIJ1DXEdDP-0-159d196be4a00d8c00dc5a92b8cba183)
(2)切换到nacos数据库下,SQL语句如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/271-2.jpg?sign=1739022354-StiNV9XYS8WezJREm2ZnEKHYg7Uz1U5R-0-0a41340024475bf73a996f3cdd816ef9)
(3)创建Nacos所需的数据库表,建表语句所在的文件位于Nacos目录下的Conf文件夹下,以下命令中的NACOS_PATH指Nacos编译成功的目录:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/271-3.jpg?sign=1739022354-qpeJwPh1Gl7S7rlVgzKRmbqm0RUf5LO1-0-70e433a2a439154afed1deb0bfa38dea)
然后,可以运行show tables命令查看数据库表是否被正确创建。
(4)修改Nacos配置文件,使用MySQL存储配置项。Nacos配置文件的路径是{NACOS_PATH}/conf/application.properties,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/271-4.jpg?sign=1739022354-JQ3iF9TPT1n4qEZW4oWOoNjOtW8t5qi0-0-c453018c0943ae1d3c5cb35c9c4adc0e)
(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所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/272-01.jpg?sign=1739022354-TNyBa1ePR7wGH0a3QmIkmzkWvVZzxSHI-0-32a94d658dfe0f61f429a3981c985025)
图6-23 在集群模式下增加配置
配置增加完毕后,再次访问Spring Boot应用的Controller接口,应用可以正确获取配置项,集群模式下的配置项获取如图6-24所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/272-02.jpg?sign=1739022354-ZFIhAQQ9NZHkwas3d4wXFFCVbvI4Qw7H-0-34fa4ed7743d1b9750411fe836d6fce5)
图6-24 集群模式下的配置项获取
检查MySQL中的数据,可以看到新添加的配置项,MySQL的配置数据如图6-25所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/272-03.jpg?sign=1739022354-15VLd9SDLnZRuHdRrg9Xdq0nAK90h8ia-0-3f6caa8a126ad9a663fbb2ef86d2a894)
图6-25 MySQL的配置数据
6.4.4 Nacos实现服务注册与服务发现
为了实现服务注册与服务发现,我们需要创建两个独立的Spring Boot应用,分别作为服务提供者和服务消费者。由于篇幅原因,本节只对主要步骤进行介绍,完整源码请参考本书的GitHub主页。
服务提供者的创建步骤如下:
(1)引入Nacos依赖,代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/273-1.jpg?sign=1739022354-b1UxUHhxmtOKqPNr0kVaZ44p9DodzXGW-0-29868755f2f8a472f6d3d99da6c8d0cd)
(2)修改bootstrap.properties文件,指定当前应用的应用名和Nacos的连接地址,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/273-2.jpg?sign=1739022354-rmgH3N4s3xsPxCMXQ5lA37WK0iWl8gHW-0-43c0f7e3fae0677e861851562427eae4)
(3)创建Application启动类,并在类上添加@EnableDiscoveryClient注解(此注解来自Spring Cloud)。
(4)创建一个名为ServiceController的测试类,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/273-3.jpg?sign=1739022354-htZoebIElB5A33aAql2KDeVcUwBCtPk0-0-de169253aec7d84c05d69e9eab5eda3f)
(5)启动应用,通过Nacos控制台的“服务管理”的“服务列表”可以查看已注册的服务名,服务注册详情如图6-26所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/273-01.jpg?sign=1739022354-BJAn0XYuBrI5pe65Z9HSJTbCDGYhmOLc-0-389bce8412d7d13b3625d32dec9be2b6)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/274-01.jpg?sign=1739022354-lrCItcVUQAiJ7ckJUoE1ugulApD5w5qE-0-4aa88de7822da50b99e34effb3c48197)
图6-26 服务注册详情
服务消费者的创建步骤如下:
(1)引入与服务提供者相同的依赖项。
(2)修改bootstrap.properties,添加以下项目:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/274-1.jpg?sign=1739022354-MVzm6k5WGOE7Tom7vvgKXuY1v5LUOWJv-0-7eca6f01e8620828dfbd9ea81dbadf72)
(3)创建启动类Application并添加EnableDiscoveryClient注释(此注释来自Spring cloud),在启动类中声明一个具有负载均衡能力的RestTemplate类,我们可以通过RestTemplate类发起远程REST接口的调用请求。Application启动类的具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/274-2.jpg?sign=1739022354-H6g5VCk8llSOrFCcp9afzkLebex1pBGp-0-eef1e360eb62b37e4bc61f6c1de08e45)
(4)创建一个测试方法,在方法中向服务提供者发起一个远程调用,具体代码如下:
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/274-3.jpg?sign=1739022354-d8BMzJ8O79Y9nuAXi5NLEz65KzVpzgVJ-0-941605155104b76a4fca85d778e39ab0)
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/275-1.jpg?sign=1739022354-nw2jpHZ0azDgKB6hyl3Gjio3ONatRHgw-0-14d4584a4c93a2ef268baa3cbfc443f7)
(5)启动应用,查看Nacos控制台的“服务管理”的“服务列表”,服务注册详情如图6-27所示。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/275-01.jpg?sign=1739022354-Xaf86qgunBack7f2duCmQbbzj79k1CkM-0-bb26dd5241736792cbfb5d4a60a35277)
图6-27 服务注册详情
打开浏览器,访问服务消费者接口(笔者本地访问路径为http://localhost:10001/consumer/hello),可以看到如图6-28所示的远程方法调用结果。
![](https://epubservercos.yuewen.com/91A00C/21440188001525406/epubprivate/OEBPS/Images/275-02.jpg?sign=1739022354-XOPV5sBVvPmFHf5khVa5BJdJi31ZXf5V-0-b2298564f20e5341962f387a27987181)
图6-28 远程方法调用结果
本章中,笔者通过示例程序演示了Nacos的基础功能,在实际工作中,特别是在大规模集群下,无论是服务注册还是配置管理都面临着非常大的技术挑战。例如,跨中心的数据一致性问题、变更推送的延迟问题,以及Nacos集群本身的容灾能力等。本章介绍的Nacos知识点只是抛砖引玉,还请读者在工作和学习中继续探索更大更广阔的Nacos应用场景。