Spring Cloud Alibaba,分布式配置(二)(下)

简介: Spring Cloud Alibaba,分布式配置(二)

5.3 使用 Nacos Config 监听实现 Bean 属性动态刷新

前文曾提及 com.alibaba.nacos.api.config.listener.Listener是 Nacos Client API 标准的配置监听器接口,由于仅监听配置内容,并不能直接与 Spring 体系打通,因此,需要借助于 Spring Cloud Alibaba Nacos Config API NacosConfigManager(感谢小伙伴 liaochuntao 和 zkzlx 的代码贡献),代码调整如下:

@SpringBootApplication
@RestController
@RefreshScope
@EnableConfigurationProperties(User.class)
public class NacosConfigSampleApplication {
    @Value("${user.name}")
    private String userName;
    @Value("${user.age}")
    private int userAge;
    @Autowired
    private User user;
    @Autowired
    private NacosConfigManager nacosConfigManager;
    @Bean
    public ApplicationRunner runner() {
        return args -> {
            String dataId = "nacos-config-sample.properties";
            String group = "DEFAULT_GROUP";
            nacosConfigManager.getConfigService().addListener(dataId, group, new AbstractListener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    System.out.println("[Listener] " + configInfo);
                }
            });
        };
    }
    @PostConstruct
    public void init() {
        System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);
    }
    @PreDestroy
    public void destroy() {
        System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);
    }
    @RequestMapping("/user")
    public String user() {
        return "[HTTP] " + user;
    }
    public static void main(String[] args) {
        SpringApplication.run(NacosConfigSampleApplication.class, args);
    }
}

代码主要变化:

  • @Autowired依赖注入 NacosConfigManager
  • 新增 runner()方法,通过 NacosConfigManagerBean 获取 ConfigService,并增加了 AbstractListener( Listener抽象类)实现,监听 dataId = “nacos-config-sample.properties” 和 group = “DEFAULT_GROUP” 的配置内容

重启应用,并将配置 user.age 从 19 调整到 90,观察日志变化:

c.a.n.client.config.impl.ClientWorker    : [fixed-127.0.0.1_8848] [data-received] dataId=nacos-config-sample.properties, group=DEFAULT_GROUP, tenant=null, md5=b0f42fac52934faf69757c2b6770d39c, content=user.name=nacos-config-sample
user.age=90, type=properties
[Listener] user.name=nacos-config-sample
user.age=90
......

在第 1 行日志下方,新增了监听实现代码的输出内容,不过这段内容是完整的配置,而非变化的内容。读者请务必注意其中的差异。下一步要解决的是将配置映射到 Bean 属性,此处给出一个简单的解决方案,实现步骤有两个:

  • 将 String 内容转化为 Properties 对象
  • 将 Properties 属性值设置到对应的 Bean 属性

代码调整如下:

@SpringBootApplication
@RestController
@RefreshScope
@EnableConfigurationProperties(User.class)
public class NacosConfigSampleApplication {
    ......
    @Bean
    public ApplicationRunner runner() {
        return args -> {
            String dataId = "nacos-config-sample.properties";
            String group = "DEFAULT_GROUP";
            nacosConfigManager.getConfigService().addListener(dataId, group, new AbstractListener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    System.out.println("[Listener] " + configInfo);
                    System.out.println("[Before User] " + user);
                    Properties properties = new Properties();
                    try {
                        properties.load(new StringReader(configInfo));
                        String name = properties.getProperty("user.name");
                        int age = Integer.valueOf(properties.getProperty("user.age"));
                        user.setName(name);
                        user.setAge(age);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("[After User] " + user);
                }
            });
        };
    }
    ......
}

重启应用,并将配置 user.age 从 90 调整到 19,观察日志变化:

[Listener] user.name=nacos-config-sample
user.age= 19
[Before User] User{name='nacos-config-sample', age=90}
[After User] User{name='nacos-config-sample', age=19}

上述三个例子均围绕着 Nacos Config 实现 Bean 属性动态更新,不过它们是 Spring Cloud 使用场景。如果读者的应用仅使用 Spring 或者 Spring Boot,可以考虑 Nacos Spring 工程, Github 地址:https://github.com/nacos-group/nacos-spring-project,其中 @NacosValue支持属性粒度的更新。

6. Nacos Config 高级配置

6.1 支持自定义 namespace 的配置

首先看一下 Nacos 的 Namespace 的概念, Nacos 概念

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

在没有明确指定 ${spring.cloud.nacos.config.namespace}配置的情况下, 默认使用的是 Nacos 上 Public 这个namespae。如果需要使用自定义的命名空间,可以通过以下配置来实现:

spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7

注:该配置必须放在 bootstrap.properties 文件中。此外 spring.cloud.nacos.config.namespace的值是 namespace 对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置

6.2 支持自定义 Group 的配置

在没有明确指定 ${spring.cloud.nacos.config.group}配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:

spring.cloud.nacos.config.group=DEVELOP_GROUP

注:该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值一定要和 spring.cloud.nacos.config.group的配置值一致。

6.3 支持自定义扩展的 Data Id 配置

Spring Cloud Alibaba Nacos Config 从 0.2.1 版本后,可支持自定义 Data Id 的配置。关于这部分详细的设计可参考 这里。一个完整的配置案例如下所示:

spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true

可以看到:

  • 通过 spring.cloud.nacos.config.extension-configs[n].data-id的配置方式来支持多个 Data Id 的配置。
  • 通过 spring.cloud.nacos.config.extension-configs[n].group的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
  • 通过 spring.cloud.nacos.config.extension-configs[n].refresh的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的。

注:多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.extension-configs[n].data-id其中 n 的值越大,优先级越高。

spring.cloud.nacos.config.extension-configs[n].data-id的值必须带文件扩展名,文件扩展名既可支持 properties,又可以支持 yaml/yml。此时 spring.cloud.nacos.config.file-extension的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。

通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件。

为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:

# 配置支持共享的 Data Id
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
# 配置 Data Id 所在分组,缺省默认 DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1
# 配置Data Id 在配置变更时,是否动态刷新,缺省默认 false
spring.cloud.nacos.config.shared-configs[0].refresh=true

可以看到:

  • 通过 spring.cloud.nacos.config.shared-configs[n].data-id来支持多个共享 Data Id 的配置。
  • 通过 spring.cloud.nacos.config.shared-configs[n].group来配置自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
  • 通过 spring.cloud.nacos.config.shared-configs[n].refresh来控制该Data Id在配置变更时,是否支持应用中动态刷新,默认false。

6.4 配置的优先级

Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置。

  • A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id支持多个共享 Data Id 的配置
  • B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id的方式支持多个扩展 Data Id 的配置
  • C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置

当三种方式共同使用时,他们的一个优先级关系是:A < B < C

6.5 完全关闭配置

通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config

6.6 更多高级配置

更多关于 Nacos Config Starter 的配置项如下所示:

配置项 Key 默认值 说明
服务端地址 spring.cloud.nacos.config.server-addr
Nacos Server 启动监听的ip地址和端口
配置对应的 DataId spring.cloud.nacos.config.name
先取 prefix,再取 name,最后取 spring.application.name
配置对应的 DataId spring.cloud.nacos.config.prefix
先取 prefix,再取 name,最后取 spring.application.name
配置内容编码 spring.cloud.nacos.config.encode
读取的配置内容对应的编码
GROUP spring.cloud.nacos.config.group DEFAULT_GROUP 配置对应的组
文件扩展名 spring.cloud.nacos.config.fileExtension properties 配置项对应的文件扩展名,目前支持 properties 和 yaml(yml)
获取配置超时时间 spring.cloud.nacos.config.timeout 3000 客户端获取配置的超时时间(毫秒)
接入点 spring.cloud.nacos.config.endpoint
地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
命名空间 spring.cloud.nacos.config.namespace
常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
AccessKey spring.cloud.nacos.config.accessKey
当要上阿里云时,阿里云上面的一个云账号名
SecretKey spring.cloud.nacos.config.secretKey
当要上阿里云时,阿里云上面的一个云账号密码
Nacos Server 对应的 context path spring.cloud.nacos.config.contextPath
Nacos Server 对外暴露的 context path
集群 spring.cloud.nacos.config.clusterName
配置成Nacos集群名称
共享配置 spring.cloud.nacos.config.sharedDataids
共享配置的 DataId, “,” 分割
共享配置动态刷新 spring.cloud.nacos.config.refreshableDataids
共享配置中需要动态刷新的 DataId, “,” 分割
自定义 Data Id 配置 spring.cloud.nacos.config.extConfig
属性是个集合,内部由 ConfigPOJO 组成。Config有 3 个属性,分别是 dataIdgroup以及 refresh

7. Nacos Config Actuator Endpoint

Nacos Config 内部提供了一个 Endpoint, 对应的 Endpoint ID 为 nacos-config,其 Actuator Web Endpoint URI 为 /actuator/nacos-config

注:使用 Nacos Config Spring Cloud 1.x 版本的话,其 URI 地址则为 /nacos-config

其中,Endpoint 暴露的 json 中包含了三种属性:

  • NacosConfigProperties: 当前应用 Nacos 的基础配置信息
  • RefreshHistory: 配置刷新的历史记录
  • Sources: 当前应用配置的数据信息

由于 Aliyun Java Initializr 所生成的应用工程默认激活 Spring Boot Actuator Endpoints(JMX 和 Web),具体配置存放在 application.properties文件中,同时,Actuator Web 端口设置为 8081,内容如下:

management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# Actuator Web 访问端口
management.server.port=8081

因此,应用 nacos-config-sample 无需调整,直接访问:http://127.0.0.1:8081/actuator/nacos-config,服务响应的内容如下:

{
  "NacosConfigProperties": {
    "serverAddr": "127.0.0.1:8848",
    "username": "",
    "password": "",
    "encode": null,
    "group": "DEFAULT_GROUP",
    "prefix": null,
    "fileExtension": "properties",
    "timeout": 3000,
    "maxRetry": null,
    "configLongPollTimeout": null,
    "configRetryTime": null,
    "enableRemoteSyncConfig": false,
    "endpoint": null,
    "namespace": null,
    "accessKey": null,
    "secretKey": null,
    "contextPath": null,
    "clusterName": null,
    "name": null,
    "sharedConfigs": null,
    "extensionConfigs": null,
    "refreshEnabled": true,
    "sharedDataids": null,
    "refreshableDataids": null,
    "extConfig": null,
    "configServiceProperties": {
      "secretKey": "",
      "namespace": "",
      "username": "",
      "enableRemoteSyncConfig": "false",
      "configLongPollTimeout": "",
      "configRetryTime": "",
      "encode": "",
      "serverAddr": "127.0.0.1:8848",
      "maxRetry": "",
      "clusterName": "",
      "password": "",
      "accessKey": "",
      "endpoint": ""
    }
  },
  "RefreshHistory": [
  ],
  "Sources": [
    {
      "lastSynced": "2020-09-14 11:11:37",
      "dataId": "nacos-config-sample.properties"
    },
    {
      "lastSynced": "2020-09-14 11:11:37",
      "dataId": "nacos-config-sample"
    }
  ]
}
目录
相关文章
|
8天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
28 0
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
26天前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
19天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
6天前
|
存储 人工智能 Java
Spring AI Alibaba 配置管理,用 Nacos 就够了
本文通过一些实操案例展示了 Spring AI Alibaba + Nacos 在解决 AI 应用中一系列复杂配置管理挑战的方案,从动态 Prompt 模板的灵活调整、模型参数的即时优化,到敏感信息的安全加密存储。Spring AI Alibaba 简化了对接阿里云通义大模型的流程,内置 Nacos 集成也为开发者提供了无缝衔接云端配置托管的捷径,整体上极大提升了 AI 应用开发的灵活性和响应速度。
|
18天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
28 1
|
1月前
|
人工智能 Java API
阿里云开源 AI 应用开发框架:Spring AI Alibaba
近期,阿里云重磅发布了首款面向 Java 开发者的开源 AI 应用开发框架:Spring AI Alibaba(项目 Github 仓库地址:alibaba/spring-ai-alibaba),Spring AI Alibaba 项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。本文将详细介绍 Spring AI Alibaba 的核心特性,并通过「智能机票助手」的示例直观的展示 Spring AI Alibaba 开发 AI 应用的便利性。示例源
|
1月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
27天前
|
消息中间件 自然语言处理 Java
知识科普:Spring Cloud Alibaba基本介绍
知识科普:Spring Cloud Alibaba基本介绍
60 2
|
1月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
127 1
下一篇
无影云桌面