Spring Cloud Alibaba——Nacos Config配置中心

前言

SpringBoot与SpringCloud版本对应关系:https://start.spring.io/actuator/info

SpringCloud与Spring-Cloud-Alibaba版本对应关系:
Spring Cloud Alibaba官方版本声明:https://github.com/alibaba/spring-cloud-alibaba/wiki

spring官网也能看到springboot与springcloud版本对应关系:https://spring.io/projects/spring-cloud-alibaba#learn

微服务中配置文件的问题

  • 1、配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。

  • 2、配置文件无法区分环境。微服务项目会有多个环境。例如:开发环境、测试环境、预发布环境、生产环境。每一个环境所使用的配置一般情况下是不同的。打个比方,出个包更新到预发布环境,还得把配置改好了才能进行,很痛苦。

  • 3、配置文件无法动态实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。

基于上述这些问题,我们就需要配置中心的加入来解决问题。

配置中心的思路是:

  • 1、首先把项目中各种配置全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。
  • 2、微服务来配置中心拉取自己的配置。
  • 3、当配置中心里面的参数有更新时,也能通知到各个微服务实时的过来同步最新的信息,使之动态更新。

业界常见配置中心

  • Apollo
  • Disconf
  • Spring Cloud Config
  • Nacos Config

Nacos Config与Spring Boot整合

引入maven依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <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-config</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement> 

三、在微服务中添加nacos config的配置

注意:不能使用原来的application.yml作为配置文件,而是新建一个bootstrap.yml作为配置文件

配置文件优先级(由高到低):
bootstrap.properties > bootstrap.yml > application.properties > application.yml
spring:
  application:
    name: service-product
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848   # Nacos配置中心的地址
        file-extension: yaml  # 配置的格式
  profiles:
    active: dev # 环境标识

四、在nacos中添加配置

五、配置动态刷新

上述操作已经实现了配置的远程存放和拉取。但是如果此时修改了配置,我们的程序是无法读取到的。因此,我们需要开启配置的动态刷新功能。

为了方便测试,在nacos中的service-product-dev.yaml配置项中添加以下配置,用于后续打印输出。

config:
  appName: jack-product
  gender: man

方式一:硬编码方式(此方式默认就支持动态刷新,但是不够简洁,不推荐)

@RestController
@RequestMapping("/nacos/config")
public class NacosConfigController {
 
    @Autowired
    private ConfigurableApplicationContext configurableApplicationContext;
    
    @RequestMapping("/test1")
    public String test1() {
        return this.configurableApplicationContext.getEnvironment().getProperty("config.appName");
    }
}

方式二:注解方式(推荐)

@RestController
@RequestMapping("/nacos/config")
@RefreshScope   // 注解方式读取配置,如果需要动态更新,需要加上此注解
public class NacosConfigController {
 
    @Value("${config.gender}")
    private String gender;
 
   
    @RequestMapping("/test2")
    public String test2() {
        return gender;
    }
}

六、配置共享

当配置越来越多的时候,就发现有很多配置是重复的,这时候就需要考虑能不能将公共配置提取出来,然后实现共享呢?当然是可以的。接下来演示如何实现这一功能。

6.1 同一个微服务的不同环境之间共享配置

如果想在同一个微服务的不同环境之间实现配置共享,其实很简单。

只需要提取一个以spring.application.name命名的配置文件,然后将所有环境的公共配置放在里面即可。

  • 第一步:新建一个名为service-product.yaml配置,用于存放商品微服务的公共配置


  • 第二步:新建一个名为service-product-test.yaml的配置,用于存放测试环境的配置


  • 第三步:修改service-product-dev.yaml的配置,存放开发环境独有的配置


  • 第四步:进行测试

@RestController
@RequestMapping("/nacos/config")
@RefreshScope   // 注解方式读取配置,如果需要动态更新,需要加上此注解
public class NacosConfigController {
 
    @Value("${config.gender}")
    private String gender;
 
   
    @RequestMapping("/test2")
    public String test2() {
        return gender;
    }
}

启动微服务,访问测试


接下来,修改bootstrap.yml中的配置,将active修改为test,再次访问测试,观察输出结果


6.2 不同微服务之间共享配置

不同微服务之间共享配置的原理,类似于文件引入,就是定义一个公共配置,然后在当前配置中引入。

  • 1、在nacos中定义一个DataId为all-service.yaml的配置,用于所有微服务共享


  • 2、修改微服务的bootstrap.yml

shared-configs配置方式
spring:
  application:
    name: service-product
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848   # Nacos配置中心的地址
        file-extension: yaml  # 配置的格式
        
        #新版本配置方式 可以配置多个
        shared-configs[0]: 
          data_id: all-service.yaml  # 要引入的配置
          group: DEFAULT_GROUP # 可以不写,默认值为DEFAULT_GROUP
          refresh: true # 默认是false,如果需要支持自动刷新需要配置true,搭配@RefreshScope实现动态刷新
          
        #老版本配置方式
        #shared-dataids: all-service.yaml  # 要引入的配置
        #refreshable-dataids: all-service.yaml # 动态刷新时也刷新引入的配置
  profiles:
    active: test # 环境标识
extension-configs配置方式
spring:
  application:
    name: service-product
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848   # Nacos配置中心的地址
        file-extension: yaml  # 配置的格式
        #新版本配置方式 可以配置多个
        extension-configs[0]: 
          data_id: service.yaml  # 要引入的配置
          group: DEFAULT_GROUP # 可以不写,默认值为DEFAULT_GROUP
          refresh: true # 默认是false,如果需要支持自动刷新需要配置true,搭配@RefreshScope实现动态刷新
        extension-configs[1]: 
          data_id: rocketmq.yaml  # 要引入的配置
          group: DEFAULT_GROUP # 可以不写,默认值为DEFAULT_GROUP
          refresh: true # 默认是false,如果需要支持自动刷新需要配置true,搭配@RefreshScope实现动态刷新
  profiles:
    active: test # 环境标识
  • 3、添加测试方法
@RestController
@RequestMapping("/nacos/config")
@RefreshScope   // 注解方式读取配置,如果需要动态更新,需要加上此注解
public class NacosConfigController {
    
    @Value("${test.name}")
    private String name;
 
    
 
    @RequestMapping("/test3")
    public String test3() {
        return name;
    }
}

7、Nacos Config动态刷新原理

动态监听

  • Push表示服务端主动将数据变更信息推送给客户端
  • Pull表示客户端主动去服务端拉取数据

Nacos 采用的是 Pull 模式,但并不是简单的 Pull,而是一种长轮训机制,它结合 Push 和 Pull 两者的优势(nacos并没有push)。客户端采用长轮训的方式定时发起 Pull 请求,去检查服务端配置信息是否发生了变更,如果发生了变更,则客户端会根据变更的数据获得最新的配置。所谓的长轮训,是客户端发起轮训请求之后,服务端如果有配置发生变更,就直接返回。

如果客户端发起 Pull 请求后,发现服务端的配置和客户端的配置是保持一致的,那么服务端会先 “Hold” 住这个请求,也就是服务端拿到这个连接之后在指定的时间段内一直不返回结果,直到这段时间内配置发生变化,服务端会把原来 “Hold” 住的请求进行返回。Nacos 服务端收到请求之后,先检查配置是否发生了变更,如果没有,则设置一个定时任务,延期 29.5s 执行,并且把当前的客户端长轮训加入 allSubs 队列。这个时候有两种方式触发该链接结果的返回:// 后面单独看config server的源码解析

  • 1、第一种是在等待 29.5s 后触发自动检查机制,这个时候不管配置有没有发生变化,都会把结果返回客户端。而 29.5s 就是这个长连接保持的时间。

  • 2、第二种是在 29.5s 内任意一个时刻,通过 Nacos Dashboard 或者 API 的方式对配置进行了修改,就会触发一个事件机制,监听该事件的任务会遍历 allSubs 队列,找到发生变更的配置项对应的 ClientLongPolling 任务,将变更的数据通过该任务的连接进行返回,就完成一次 “推送” 操作。

这样既能够保证客户端实时感知配置的变化,也降低了服务端的压力。其中,这个长连接的会话超时时间默认是 30s。

nacos config 动态刷新流程图
nacos config 动态刷新流程图

参考:
https://blog.csdn.net/qq_31155349/article/details/108818208

https://beijingngcc.blog.csdn.net/article/details/113288021

https://zhuanlan.zhihu.com/p/556412488

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容