SpringCloud系列(七)| 集成Nacos配置中心

1、关于配置中心

在说配置中心之前,我们先说说配置文件,关于这个词,我想大家并不陌生。 不管是前端,后端或是其他的各类技术栈,应该都离不来配置文件。我们在早期的代码开发时代,就经常和配置文件打交道, 什么web.xml, applicationContext.xml,mybatis-config.xml、hibernate.cfg.xml, 等等等等(熟悉这些文件名称的应该都是老司机了)。

配置文件的主要目的就是帮我我们把一些容易发生变化的参数户或变量从代码中分类出来,放到一个单独的文件中进行存储,方便我们进行统一的管理和配置。同时也方便我们在多套环境进行切换时,避免进行重复的修改打包等操作。

但是随着微服务发展,服务的数量不断增多,而配置文件的数量也不断增多,传统的配置文件,也暴露出了诸多不足。比如修改的实时性无法得到保证,发布的时候,经常将本地配置发布到生产环境,引发事故,同时没有版本控制机制,权限机制等问题。

所以配置中心应运而生,配置中心就是将所有的配置从各个应用中剥离出来,统一放到一个地方,对所有配置进行单独统一的管理。 而在SpringCloud微服务体系中,配置中心也成为了他的一个标准功能组件。当然该组件也不是必须有的,我们可以根据自己的项目需求进行选用。

总结一下,配置中心的主要作用: 统一维护,环境隔离,实时生效,最好还有版本管理、灰度发布、权限控制、审核机制等

常见的配置中心有这么几种:

  • SpringCloud Config: 官方推出的配置中心组件, 基于git进行配置存储,实时刷新需要通过消息总线实现。
  • apollo: 携程开源的配置中心,具备规范的权限、流程治理等特性
  • SpringCloud alibaba nacos: 集注册中心和配置中心功能于一身,SpringCloudalibaba 生态代表产品。

由于我们目前介绍alibaba生态较多。前面也介绍了nacos作为注册中心的用法,今天重点介绍nacos作为配置中心该如何使用。

2、集成nacos配置中心

再给一下官网地址: nacos.io/zh-cn/docs/...

为了方便演示,我们先优化一下我们的分支策略。 先拉取一个01_nacos_discovery_feign 分支,这个分支主要就是我们之前的代码,集成了nacos配置中心和feign 服务调用。 然后在拉取一个 02_nacos_config分支,我们在这个分支上进行nacos配置中心的集成开发。

2.1 引入依赖

xml 复制代码
<!-- SpringCloud Ailibaba Nacos Config -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

我们可以把这个在各个微服务中引入,也可以再commons模块中引入。 我们就在各个微服务中引用吧,放到commons中其实不是太好,不够灵活,万一后面某个服务不需要这个包了,还得排除掉。就在userservice和orderservice中分别添加一下。

2.2 页面操作

nacos为我们提供了配置页面,方便我们进行操作和配置,在这个页面中,我们可以创建命名空间、管理配置,查看注册的服务,还可以配置访问的权限等。

打开我们的nacos页面: http://10.211.55.11:8848/nacos/#/

先来讲解几个概念,在nacos配置中心中,有三个比较重要的概念,分别是:

namespace, group, dataId

  • Namespace: 代表不同的环境, 如: 开发、测试, 生产等
  • Group: 可以代表某个项目, 如XX医疗项目, XX电商项目
  • DataId: 每个项目下往往有若干个工程, 每个配置集(DataId)是一个工程的主配置文件

配置图:

所以要想使用配置中心,这三个东西必不可少。

我们先来创建一个namespace:

创建好之后,在配置列表中,就会出现这个命名空间:

我们进入这个namespace, 点击加号创建一个配置:

这个配置的dataId 设置为: userservice-dev。 组的话,我们就使用默认的组,当然也可以自己创建。 然后添加了一个变量: userservice.retry.count

那么我们的程序,如何能够读取到这个配置文件呢,就需要在我们的程序中的配置文件里,加入nacos配置中心的地址,然后通过dataId就可以找到对应的配置了,那么我们就在程序中也配置一下。

2.3 添加配置

在SpringCloud的微服务体系中,一般我们集成了配置中心,都是将全局配置添加到bootstrap.yml (或者是bootstrap.properties)中, 比如应用名称,nacos的地址等。 bootstrap.yml 本质上作用和application.yml的一样,只不过bootstrap.yml执行在applicaton.yml之前。 所以我们直接在resources下创建一个bootstrap.yml将配置写入该文件中,同时可以删除掉application.yml。

同时要注意bootstrap.yml只能在springCloud项目中使用,单独在SpringBoot中使用是读取不了的。

我们先以userservice为例。 在userservice的bootstrap.yml中添加配置:

yml 复制代码
server:
  port: 8084

spring:
  application:
    name: userservice
  profiles:
    active: dev
  cloud:
    nacos:
    discovery:
      server-addr: 10.211.55.11:8848
    config:
      server-addr: 10.211.55.11:8848
      file-extension: yaml
      namespace: dev

大致配置如上。

这里要注意,我们无需配置dataId, 代码中dataId 的组成规则是:

prefix−{prefix}-prefix−{spring.profiles.active}-${file-extension}

  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 **注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ** ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

所以根据上面的规则,可以看出我们的dataId 就是 userservice-dev.yaml 和刚刚页面上配置的dataId刚好可以及对应上,那我们就来验证下能否读取到在配置中心中配置的变量。

注意: 如果file-extension写的是yml, nacos中的文件名就要叫userservice-dev.yml, 如果配置的是yaml, 那么文件名就叫userservice-dev.yaml。 一定要保持一致。

2.4 配置验证

我们在Controller中添加一个属性和一个方法,用来读取配置文件中的变量:

java 复制代码
@Value("${userservice.retry.count}")
private Integer count;
    
@GetMapping("getCount")
public Result getCount(){
    return Result.success(count);
}
    

同时还有一点需要注意,由于我们使用的springBoot版本比较新.Spring Boot 2.4版本开始,配置文件加载方式进行了重构.

2.4之前的版本: spring.cloud.bootstrap.enabled 默认值是true

2.4.2 之后的版本默认值变成了false, 所以我们需要先打开这个配置,才能启用bootstrap的配置。

ini 复制代码
IDEA中:
spring.cloud.bootstrap.enabled=true

启动命令中: 
java -jar -Dspring.cloud.bootstrap.enabled=true xxx.jar

idea中的配置方法:

添加一个VM Options。 然后在运行程序。

http://localhost:8084/user/getCount

获取到结果:

json 复制代码
{
  code: 0,
  msg: "操作成功",
  data: 3
}

data值为3。

3、 实时刷新

通过上述内容,我们已经实现了对于配置中心的集成,也成功的将配置文件的内容放到了配置中心中,并且可以成功读取,接下来我们来实验一下试试刷新。

我们现在nacos的页面配置里,变量3改为30,然后点击发布。

这个时候,我们继续执行程序,看得到的结果:

http://localhost:8084/user/getCount

json 复制代码
{
  code: 0,
  msg: "操作成功",
  data: 3
}

发现得到的值还是3, 并没有进行实时刷新。这也就说明nacos是默认不进行实时刷新的,要想刷新,必须重新启动应用。那么该如何配置呢,可以通过注解 @RefreshScope来配置。

将这个注解放到对应类中,那么这个类中使用的变量就可以试试刷新。

注意: RefreshScope注解不能放到启动类上,放到启动类上是没有任何实时刷新效果的。哪个类里用到了就在对应的类上加,同时要注意,这个类一定要被Spring容器管理。

重新启动程序。

调用程序肯定得到的是30。因为我们重启了应用,修改nacos的值为300,点击发布,这个时候,不重启应用,来看结果,发现已经实时发生变化。

4、nacos鉴权

nacos默认访问是不需要用户名和密码的,但是这样一旦被别人发现了nacos的地址,其实是比较危险的,所以nacos也提供了鉴权服务。

鉴权服务需要在nacos的安装程序中进行修改。

找到 安装目录/conf/application.properties文件。 将配置nacos.core.auth.enabled的值由false改为true

修改之后,无需重启,立即生效。

此时我们的项目就会发现报错了:

我们需要在使用nacos的时候带上用户名和密码:

yaml 复制代码
spring:
  application:
    name: userservice
  profiles:
    active: dev
  cloud:
    nacos:
      username: nacos
      password: nacos
      discovery:
        server-addr: 10.211.55.11:8848
      config:
        server-addr: 10.211.55.11:8848
        file-extension: yml
        namespace: dev-1234567890
        group: DEFAULT_GROUP

加入了username和password属性,此时在启动就可以成功了。

除了用户名密码的方式,nacos也支持采用自定义秘钥的方式,我们可以自己生成一对秘钥,在nacos中进行配置。具体可参照:nacos.io/zh-cn/docs/...

5、配置共享

如果多个服务的配置中有一些相同的服务,我们可以把他们抽取出来。 比如redis的连接信息, 各个服务使用的都是相同的,就可以将其做成一个共享服务。

创建一个redis-dev.yml

yaml 复制代码
spring:
  redis:
    password: 123456
    cluster:
      nodes: redis1:7000,redis1:7001,redis2:7000,redis2:7001,redis3:7000,redis3:7001
      max-redirects: 3
    lettuce:
      pool:
        max-idle: 16
        max-active: 32
        min-idle: 8

然后在各个需要依赖该配置的bootstrap.yml中添加共享:

yaml 复制代码
spring:
  cloud:
    nacos:
      config:
        extension-configs:
          - data-id: redis-dev.yml
            group: middleware
            refresh: true

extension-configs: 配置的是一个数组, 可以有有多个, 参数就是对应的data-id, group, 和refresh。

这个还是比较实用的。

nacos配置中心的使用虽然比较简单,但是里面的细节还是比较多的,但是大家如果掌握了上述几点,使用起来还是没有任何问题的。好了关于nacos配置中心的内容我们就讲解这么多,相关代码已上传至gitCode。我们下期再见。

相关推荐
想进大厂的小王25 分钟前
Spring-cloud 微服务 服务注册_服务发现-Eureka
微服务·eureka·服务发现
代码之光_198025 分钟前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi30 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
颜淡慕潇1 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
尘浮生2 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料2 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理
monkey_meng3 小时前
【Rust中的迭代器】
开发语言·后端·rust
余衫马4 小时前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng4 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
Gemini19954 小时前
分布式和微服务的区别
分布式·微服务·架构