【Spring Cloud Alibaba】Nacos 分布式配置

一、Nacos 分布式配置

1、Nacos 概念

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。Nacos 的获取和启动方式可以参考 Nacos 官网。

2、Nacos 安装

  • Nacos 官网文档:https://nacos.io/zh-cn/docs/quick-start.html
  • 下载 Nacos:https://github.com/alibaba/nacos/releases/tag/1.3.2(推荐下载1.3.2的版本)

下载之后修改 bin/startup.cmd,找到 MODE,修改模式从集群修改为单击模式

set MODE="cluster"

修改为

set MODE="standalone"

双击 startup.cmd 则启动 Nacos,直接访问提示的地址,默认账号密码都是 nacos

【Spring Cloud Alibaba】Nacos 分布式配置我这里的访问地址就是:http://192.168.10.3:8848/nacos/index.html【Spring Cloud Alibaba】Nacos 分布式配置

二、Nacos 实战

1、搭建项目

项目名字设置为:spring-cloud-alibaba-learn,后面需要用到配置

使用官网提供的脚手架(https://start.aliyun.com/bootstrap.html),选择以下几个组件:

  • Nacos Config
  • Spring Web
  • Spring Boot Actuator【Spring Cloud Alibaba】Nacos 分布式配置

2、配置 Nacos

在 Nacos 的命名空间增加一个空间配置:sandbox-configuration 并且新增配置,配置的 DataID 为:spring-cloud-alibaba-learn.properties

【Spring Cloud Alibaba】Nacos 分布式配置然后编辑该配置,增加两个属性

【Spring Cloud Alibaba】Nacos 分布式配置

3、项目配置

修改 bootstrap.properties 文件

# 应用名称
spring.application.name=spring-cloud-alibaba-learn

# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
# Nacos认证信息
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
spring.cloud.nacos.config.contextPath=/nacos
# 设置配置中心服务端地址
spring.cloud.nacos.config.server-addr=localhost:8848
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
spring.cloud.nacos.config.namespace=sandbox-configuration
spring.cloud.nacos.config.file-extension=properties

4、读取配置属性

package cn.tellsea;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;

/**
 * @author Tellsea
 * @date 2021/12/17
 */

@SpringBootApplication
public class SpringCloudAlibabaLearnApplication {

    @Value("${user.name}")
    private String userName;
    @Value("${user.age}")
    private int userAge;

    @PostConstruct
    public void init() {
        System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudAlibabaLearnApplication.classargs);
    }

}

控制台输出以下信息,则表示配置完成了

[init] user name : Tellsea , age : 22

5、实现 Bean @Value 属性动态刷新

修改上一节的启动类,增加@RestController、@RefreshScope 注解,并增加一个访问接口

package cn.tellsea;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;

/**
 * @author Tellsea
 * @date 2021/12/17
 */

@SpringBootApplication
@RestController
@RefreshScope
public class SpringCloudAlibabaLearnApplication {

    @Value("${user.name}")
    private String userName;
    @Value("${user.age}")
    private int userAge;

    @PostConstruct
    public void init() {
        System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);
    }

    @RequestMapping("/user")
    public String user() {
        return String.format("[HTTP] user name : %s , age : %d", userName, userAge);
    }

    @PreDestroy
    public void destroy() {
     // 这里可以观察到,修改了配置之后,调用了销毁的方法
        System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudAlibabaLearnApplication.classargs);
    }

}

我们可以看到控制台一样你的输出信息,使用浏览器访问接口http://localhost:8080/user,同样的输出相同的配置

然后我们修改 nacos 的配置,将 user.age=20,修改为 user.age=99,然后再请求 user 接口,查看配置信息,已经是修改后的配置参数了。这里需要注意一点,这种方式刷新 Bean,是通过销毁 Bean 重新初始化的方式,来实现属性值的修改

6、实现@ConfigurationProperties Bean 属性动态刷新

创建一个 User 的实体类

package cn.tellsea.nacosconfig;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;

/**
 *
 * @author Tellsea
 * @date 2021/12/20
 */

@RefreshScope
@ConfigurationProperties(prefix = "user")
public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

修改启动类的配置

package cn.tellsea;

import cn.tellsea.nacosconfig.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author Tellsea
 * @date 2021/12/17
 */

@SpringBootApplication
@RestController
@RefreshScope
@EnableConfigurationProperties(User.class)
public class SpringCloudAlibabaLearnApplication 
{

    @Value("${user.name}")
    private String userName;
    @Value("${user.age}")
    private int userAge;

    @Autowired
    private User user;

    @PostConstruct
    public void init() {
        System.out.printf("[init] user name : %s , age : %d%n", userName, userAge);
    }

    @RequestMapping("/user")
    public String user() {
        return String.format("[HTTP] user name : %s , age : %d", userName, userAge);
    }

    @RequestMapping("/user2")
    public String user2() {
        return "[HTTP] " + user;
    }

    @PreDestroy
    public void destroy() {
        System.out.printf("[destroy] user name : %s , age : %d%n", userName, userAge);
    }


    public static void main(String[] args) {
        SpringApplication.run(SpringCloudAlibabaLearnApplication.classargs);
    }

}

然后将 nacos 的配置的参数修改了,再访问 user2 的接口,一样的拿到了修改之后的 Bean

[HTTP] User{name='Tellsea', age=99}

7、监听实现 Bean 属性动态刷新

package cn.tellsea;

import cn.tellsea.nacosconfig.User;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;

/**
 * @author Tellsea
 * @date 2021/12/17
 */

@SpringBootApplication
@RestController
@RefreshScope
@EnableConfigurationProperties(User.class)
public class SpringCloudAlibabaLearnApplication 
{

    @Autowired
    private User user;
    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Bean
    public ApplicationRunner runner() {
        return args -> {
            String dataId = "spring-cloud-alibaba-learn.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);
                        }
                    });
        };
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudAlibabaLearnApplication.classargs);
    }

}

观察日志输出结果

user.age=22, type=properties
[Listener] user.name=Tellsea
user.age=22
[Before User] User{name='Tellsea', age=99}
[After User] User{name='Tellsea', age=22}

8、Nacos 提供了断点监控

配置文件中有以下断点监控信息

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

访问http://127.0.0.1:8081/actuator,查看actuator所有监控点【Spring Cloud Alibaba】Nacos 分布式配置访问http://127.0.0.1:8081/actuator/nacos-config,查看actuator所有监控点【Spring Cloud Alibaba】Nacos 分布式配置

微信公众号


原文始发于微信公众号(花海里):【Spring Cloud Alibaba】Nacos 分布式配置

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/69519.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!