8、Nacos统一配置管理

当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。

 

 

Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。

1.在nacos中添加配置文件

 

 然后在弹出的表单中,填写配置信息:

 注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。

2.从微服务拉取配置

微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。

但如果尚未读取application.yml,又如何得知nacos地址呢?

因此spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下

 1)引入nacos-config依赖

首先,在user-service服务中,引入nacos-config的客户端依赖:

<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2)添加bootstrap.yaml

然后,在user-service的resource下添加一个bootstrap.yaml文件,内容如下:

spring:
application:
name: user-service # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
discovery:
namespace: f81f5f9b-6eaf-4766-92f0-2479c9c73ebc # 服务注册在哪个命名空间ID
cluster-name: HZ # 集群名称
config:
file-extension: yaml # 文件后缀名
group: DEFAULT_GROUP # 分组

同时将 application.yml 文件中相同的内容删除,剩余内容如下

server:
  port: 5601
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据

${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}作为文件id,来读取配置。

本例中,就是去读取userservice-dev.yaml

3)读取nacos配置

在user-service中的UserController中添加业务逻辑,读取pattern.dateformat配置:

package cn.itcast.user.web;

import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Value("${pattern.dateformat}")
    private String dateformat;
    
    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
    // ...略
}

 重启user-service服务在页面访问,可以看到效果:

3.配置热更新

我们最终的目的,是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新

 

要实现配置热更新,可以使用两种方式:

方式一

在@Value注入的变量所在类上添加注解 @RefreshScope:

方式二(推荐)

使用@ConfigurationProperties注解代替@Value注解。

在user-service服务中,添加一个类,读取patterrn.dateformat属性:

package cn.itcast.user.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dataFormat;
}

在UserController中使用这个类代替@Value:

package cn.itcast.user.web;

import cn.itcast.user.config.PatternProperties;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import 
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private PatternProperties patternProperties;

    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDataFormat()));
    }

}

4.配置多环境共享

public命名空间下:user-service.yml

public命名空间下:user-service-sit.yml

public命名空间下:user-service-dev.yml

 

sit命名空间下:user-service-sit.yml

dev命名空间下:user-service-dev.yml

 

其实微服务启动时,会去nacos读取多个配置文件,例如:

  • [spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml

  • [spring.application.name].yaml,例如:userservice.yaml

      而[spring.application.name].yaml不包含环境,因此可以被多个环境共享。

 无论profile如何,[spring.appliction.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件

 

注意:bootstrap.yaml 的未配置 namespace 时,默认查询 public 命名空间中上面的两个配置文件,当配置 namespace 命名空间,则只会在当前命名空间中搜索上面的两个配置文件,故需要做多环境共享配置,需要在public空间创建配置文件,在 bootstrap.yaml 的 config 下不配置 namespace 字段

spring:
  application:
    name: user-service # 服务名称
  profiles:
    active: sit #开发环境,这里是dev
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      discovery:
        namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94   # 命名空间ID,用作环境隔离,服务注册在哪个命名空间
        cluster-name: HZ # 集群名称
      config:
        file-extension: yaml # 文件后缀名
        group: DEFAULT_GROUP
        # namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94  # 命名空间ID,用作在哪个空间查找 user-service.yaml、user-service-sit.yaml 文件; 无该字段,默认从 public 空间查找

 

下面我们通过案例来测试配置共享

1)添加一个环境共享配置

我们在nacos中添加一个user-service.yaml文件:

2)在user-service中读取共享配置

在user-service服务中,修改PatternProperties类,读取新添加的属性:

 在user-service服务中,修改UserController,添加一个方法:

这样,在不同命名空间的服务实例就都可以访问到 user-service.yaml文件中的值

 

5.多服务共享配置

1、在public下创建common.yaml 文件

2、在要使用该配置文件的服务中 bootstrap.yaml 增加   shared-configs  或  extension-configs

 

不同微服务之间可以共享配置文件,通过下面的两种方式来指定

方式一:

spring:
  application:
    name: user-service # 服务名称
  profiles:
    active: sit #开发环境,这里是dev
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      discovery:
        namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94   # 命名空间ID,用作环境隔离,服务注册在哪个命名空间
        cluster-name: HZ # 集群名称
      config:
        file-extension: yaml # 文件后缀名
        group: DEFAULT_GROUP
        # namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94  # 命名空间ID,用作在哪个空间查找 user-service.yaml、user-service-sit.yaml 文件
        shared-configs:  # 多服务间共享的配置列表
          - dataId: common.yaml      # 本服务要读取的共享配置文件名称

方式二:

spring:
  application:
    name: order-service # 服务名称
  profiles:
    active: sit #开发环境,这里是dev
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      discovery:
        namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94   # 命名空间ID,用作环境隔离,服务注册在哪个命名空间
        cluster-name: HZ # 集群名称
        ephemeral: false # 设置为非临时实例
      config:
        file-extension: yaml # 文件后缀名
        group: DEFAULT_GROUP
        # namespace: 53955767-95e1-4b5d-9ad9-4b0fa7ac8d94  # 命名空间ID,用作在哪个空间查找 user-service.yaml、user-service-sit.yaml 文件
        extension-configs: # 多服务间共享的配置列表
          - dataId: common.yaml      # 本服务要读取的共享配置文件名称

 

添加相应的配置读取文件,加注解 @ConfigurationProperties 

package cn.itcast.order.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@Data
@ConfigurationProperties(prefix = "common")
public class CommonProperties {
    private String name;
}

在Controller 类中使用

package cn.itcast.order.web;

import cn.itcast.order.config.CommonProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("order")
public class OrderController {

   @Autowired
   private CommonProperties commonProperties;

    @GetMapping("common")
    public String common() {
        return commonProperties.getName();
    }
}

 重启服务,浏览器访问   http://ip:port/order/common

可以看到能够返回了  common.yaml 文件中配置的 common.name 字段值

posted @ 2022-12-07 22:17  DeyouKong  阅读(196)  评论(0编辑  收藏  举报