Nacos学习(六):Nacos配置中心服务端设置与客户端的调用

mac2025-09-20  63

本文记录Nacos做为配置中心,服务器端的设置与客户端几种的访问方式。 实验用的环境如下: Nacos Server集群: 192.168.20.30:8848 192.168.20.31:8848 192.168.20.32:8848

Nacos地址服务器: 192.168.20.33:8080

客户端: 192.168.20.100

为演示方便,我们假设Nacos Client上将使用如下的配置项 user-dev.properties: user.type=user.dev user.name=user_dev user.birthday=2011-12-12 user.age=10

user-test.properties: user.type=user.test user.name=user_test user.birthday=2011-12-13 user.age=11

manager-dev.properties: manager.type=manager.dev user.name=manager_dev user.birthday=2011-12-14 user.age=12

manager-test.properties: manager.type=manager.test user.name=manager_test user.birthday=2011-12-15 user.age=13

一、在Nacos Service上创建配置 1、创建namespace namespace按"用户id:groupid:版本"设置为:"01:com.hhao.erp:01",如图:

2、分别创建以下Data Id:

DataId:user-dev.properties Group:erp-user 配置内容: user.type=user.dev user.name=user_dev user.birthday=2011-12-12 user.age=10

DataId:user-test.properties Group:erp-user 配置内容: user.type=user.test user.name=user_test user.birthday=2011-12-13 user.age=11

DataId:manager-dev.properties Group:erp-manager 配置内容: manager.type=manager.dev user.name=manager_dev user.birthday=2011-12-14 user.age=12

DataId:manager-test.properties Group:erp-manager 配置内容: manager.type=manager.test user.name=manager_test user.birthday=2011-12-15 user.age=13

二、创建Nacos Client nacos client的Pom文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.2.0.RELEASE</version>         <relativePath/> <!-- lookup parent from repository -->     </parent>     <groupId>com.hhao.nacos</groupId>     <artifactId>nacos-client</artifactId>     <version>0.0.1-SNAPSHOT</version>     <name>nacos-client</name>     <description>Demo project for Spring Boot</description>

    <properties>         <java.version>1.8</java.version>         <spring-cloud.version>Hoxton.RC1</spring-cloud.version>     </properties>

    <dependencies>         <dependency>             <groupId>com.alibaba.cloud</groupId>             <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>         </dependency>

        <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>

        <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-devtools</artifactId>             <scope>runtime</scope>         </dependency>

        <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>             <exclusions>                 <exclusion>                     <groupId>org.junit.vintage</groupId>                     <artifactId>junit-vintage-engine</artifactId>                 </exclusion>             </exclusions>         </dependency>     </dependencies>

    <dependencyManagement>         <dependencies>             <dependency>                 <groupId>org.springframework.cloud</groupId>                 <artifactId>spring-cloud-dependencies</artifactId>                 <version>${spring-cloud.version}</version>                 <type>pom</type>                 <scope>import</scope>             </dependency>             <dependency>                 <groupId>com.alibaba.cloud</groupId>                 <artifactId>spring-cloud-alibaba-dependencies</artifactId>                 <version>2.2.0.BUILD-SNAPSHOT</version>                 <type>pom</type>                 <scope>import</scope>             </dependency>         </dependencies>

    </dependencyManagement>

    <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build>

    <repositories>         <repository>             <id>spring-milestones</id>             <name>Spring Milestones</name>             <url>https://repo.spring.io/milestone</url>         </repository>     </repositories> </project> 不得不说的是:在项目中,Spring Cloud用到了Hoxton.RC1版本,但是Spring官网上最新的spring-cloud-alibaba-dependencies不支持该版本; 以下是此时Spring官网上最新的spring-cloud-alibaba-dependencies版本 <dependencyManagement>     <dependencies>         <dependency>             <groupId>com.alibaba.cloud</groupId>             <artifactId>spring-cloud-alibaba-dependencies</artifactId>             <version>2.1.0.RELEASE</version>             <type>pom</type>             <scope>import</scope>         </dependency>     </dependencies> </dependencyManagement> 所以从阿里spring-cloud-alibaba下载了最新的spring-cloud-alibaba-dependencies https://github.com/alibaba/spring-cloud-alibaba 版本如下:             <dependency>                 <groupId>com.alibaba.cloud</groupId>                 <artifactId>spring-cloud-alibaba-dependencies</artifactId>                 <version>2.2.0.BUILD-SNAPSHOT</version>                 <type>pom</type>                 <scope>import</scope>             </dependency> 可以看到,还只是SNAPSHOT,实际上它也无法支持Spring Cloud Hoxton.RC1版本,所以,没有办法,下载了源码,修改了Maven依赖项,重新编绎生成2.2.0.BUILD-SNAPSHOT,让其支持到Spring Cloud Hoxton.RC1版本。所以,如果按上述POM设置运行不起来,可以降低Spring Cloud版本,但是具体除到哪个版本,没有试过。 真希望阿里的更新能够更加及时些。

三、客户端访问、监听配置中心的user.properties 客户端application.properties设置如下: server.port=8080 #启用的配置文件 spring.profiles.active=dev #激活所有的端点的web方式请求 management.endpoints.web.exposure.include=*

客户端添加bootstrap.properties,并设置如下: #接入点,地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 spring.cloud.nacos.config.endpoint=192.168.20.33:8080 #配置中心的命名空间 spring.cloud.nacos.config.namespace=390a21f0-1826-4109-bfa6-c963fb170d59 #Group spring.cloud.nacos.config.group=erp-user #DataId前缀,默认等于spring.application.name spring.cloud.nacos.config.prefix=user #dataID后缀及内容文件格式,dataId的后缀,同时也是配置内容的文件格式,支持 properties,yml\yaml spring.cloud.nacos.config.file-extension=properties #配置内容的编码方式 spring.cloud.nacos.config.encode=UTF-8 #获取配置的超时时间,单位为ms spring.cloud.nacos.config.timeout=3000

为什么配置要放在bootstrap.properties或bootstrap.yml里呢?因为在Spring Boot中,bootstrap.properties(或bootstrap.yml)会优先于application.properties(或application.yml)加载,因此,在后续的配置中可以使用到它

创建UserEndpoint类:

/**  * @author Wan  * @date 2019/10/31 9:59  */ @RefreshScope @RestController public class UserEndpoint {     @Value("${user.type}")     String type;

    @Value("${user.name}")     String name;

    @Value("${user.age}")     Integer age;

    @Value("${user.birthday}")     @DateTimeFormat(pattern = "yyyy-MM-dd")     LocalDate birthday;

    @Autowired     private NacosConfigManager nacosConfigManager;

    @GetMapping("/info")     public String info(){         return type + name + age + birthday + nacosConfigManager.getConfigService().getServerStatus();     } }

创建监听类NacosUserListener: @Component public class NacosUserListener implements ApplicationRunner {     @Value("${user.type}")     String type;

    @Value("${user.name}")     String name;

    @Value("${user.age}")     Integer age;

    @Value("${user.birthday}")     @DateTimeFormat(pattern = "yyyy-MM-dd")     LocalDate birthday;

    @Autowired     private NacosConfigManager nacosConfigManager;

    @Override     public void run(ApplicationArguments args) throws Exception {         System.out.println(String.format("Initial type=%s,name=%s,age=%d,birthday=%s",type, name, age,birthday.format(DateTimeFormatter.BASIC_ISO_DATE)));

    //注意,直接用dataID的都不支持自动配置文件项的匹配         nacosConfigManager.getConfigService().addListener(                 "user-dev.properties", "erp-user", new Listener() {

                    /**                      * Callback with latest config data.                      *                      * For example, config data in Nacos is:                      *                      * user.name=Nacos user.age=25                      * @param configInfo latest config data for specific dataId in Nacos                      * server                      */                     @Override                     public void receiveConfigInfo(String configInfo) {                         Properties properties = new Properties();                         try {                             properties.load(new StringReader(configInfo));                         }                         catch (IOException e) {                             e.printStackTrace();                         }                         System.out.println("config changed: " + properties);                     }

                    @Override                     public Executor getExecutor() {                         return null;                     }                 });     } }

启动类NacosClientApplication: @SpringBootApplication public class NacosClientApplication {     public static void main(String[] args) {         SpringApplication.run(NacosClientApplication.class, args);     } } 启动NacosClientApplication。 访问http://192.168.20.100:8080/info看输出,也可以看Console中看输出。 可以在Nacos Server端变更属性值,在客户端可以看到值的变更响应; 可以在Nacos 客户端的application.propertis中修改源活的配置文件为spring.profiles.active=test,查看加载属性的不同;

四、客户端同时访问user.properties和manager.properties 修改bootstrap.properties,设置如下:

#接入点,地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 spring.cloud.nacos.config.endpoint=192.168.20.33:8080 #配置中心的命名空间 spring.cloud.nacos.config.namespace=390a21f0-1826-4109-bfa6-c963fb170d59 #user.properties加载,注意,此种方式不支持配置文件组合成data-id,须要自己处理成user-dev.properties或user-test.properties,nacos的不足 spring.cloud.nacos.config.ext-config[0].data-id=user-dev.properties spring.cloud.nacos.config.ext-config[0].group=erp-user spring.cloud.nacos.config.ext-config[0].refresh=true #manager.properties加载,注意,此种方式不支持配置文件组合成data-id,须要自己处理成manager-dev.properties或manager-test.properties,nacos的不足 spring.cloud.nacos.config.ext-config[1].data-id=manager-dev.properties spring.cloud.nacos.config.ext-config[1].group=erp-manager spring.cloud.nacos.config.ext-config[1].refresh=true

#配置内容的编码方式 spring.cloud.nacos.config.encode=UTF-8 #获取配置的超时时间,单位为ms spring.cloud.nacos.config.timeout=3000

修改NacosUserListener类,查看是否两个配置都加载了,以及加载后如果属性重复,则nacos的处理方法。 @Component public class NacosUserListener implements ApplicationRunner {     @Value("${manager.type}")     String managerType;

    @Value("${user.type}")     String type;

    @Value("${user.name}")     String name;

    @Value("${user.age}")     Integer age;

    @Value("${user.birthday}")     @DateTimeFormat(pattern = "yyyy-MM-dd")     LocalDate birthday;

    @Autowired     private NacosConfigManager nacosConfigManager;

    @Override     public void run(ApplicationArguments args) throws Exception {         System.out.println(String.format("Initial type=%s %s,name=%s,age=%d,birthday=%s",type,managerType ,name, age,birthday.format(DateTimeFormatter.BASIC_ISO_DATE)));

        nacosConfigManager.getConfigService().addListener(                 "user.properties", "erp-user", new Listener() {

                    /**                      * Callback with latest config data.                      *                      * For example, config data in Nacos is:                      *                      * user.name=Nacos user.age=25                      * @param configInfo latest config data for specific dataId in Nacos                      * server                      */                     @Override                     public void receiveConfigInfo(String configInfo) {                         Properties properties = new Properties();                         try {                             properties.load(new StringReader(configInfo));                         }                         catch (IOException e) {                             e.printStackTrace();                         }                         System.out.println("config changed: " + properties);                     }

                    @Override                     public Executor getExecutor() {                         return null;                     }                 });     } } 运行NacosClientApplication,输出:

可以看到,两个项都加载,但合并后相同的属性,后面的会覆盖前面的。

五、客户端同时访问user.properties和manager.properties另一种方式 修改bootstrap.properties,设置如下: #接入点,地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 spring.cloud.nacos.config.endpoint=192.168.20.33:8080

spring.cloud.nacos.config.shared-data-ids=user-dev.properties,manager-dev.properties spring.cloud.nacos.config.refreshable-dataids=user-dev.properties,manager-dev.properties

#配置内容的编码方式 spring.cloud.nacos.config.encode=UTF-8 #获取配置的超时时间,单位为ms spring.cloud.nacos.config.timeout=3000

用shared-data-ids和refreshable-dataids配置共享的多个配置项(refreshable-dataids控制刷新),不过,这种方式只支持默认的public命名空间、DEFAULT_GROUP的Group,所以Nacos Server端要在public命名空间、DEFAULT_GROUP组下创建user-dev.properties,manager-dev.properties配置项。 这种局限还挺大的,nacos代码这部份没有完善。

终上所述,目前比较靠谱的加载方法即第二种: spring.cloud.nacos.config.ext-config[1].data-id=manager-dev.properties spring.cloud.nacos.config.ext-config[1].group=erp-manager spring.cloud.nacos.config.ext-config[1].refresh=true 不过,这种也有缺限,不像第一种那样,能够自动识别配置文件。不过,一般情况下,配置环境的分隔可以话到Nacos服务器地址那去做,这里也就无所谓配置文件了。 所以,尽量不要在data id中用到配置文件的标识。

六、关于@RefreshScope 在这个范围内的所有bean 仅在首次访问时初始化,所以这个范围强制懒加载。这个注解会给范围内的每个bean创建个代理对象. 如果刷新bean,则下次访问bean时(即执行方法)将创建一个新实例。所有生命周期方法都应用于bean实例,因此在刷新时会调用在bean工厂的销毁回调方法,然后在创建新实例时正常调用初始化回调。从原始bean定义创建新的bean实例,因此在创建时会重新评估任何外化内容(属性占位符或字符串文字中的表达式)

所以这段话的重点就是: 所有@RefreshScope的Bean都是延迟加载的,只有在第一次访问时才会初始化 刷新Bean也是同理,下次访问时会创建一个新的对象

七、@ConfigurationProperties应用 package com.hhao.erp.user.endpoint;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;

/**  * @author Wan  * @date 2019/11/4 10:15  */ @RestController public class UserEndpoint2 {     @Autowired     UserConfigProperties properties;

    @RequestMapping("/info2")     public UserConfigProperties getProperties(){         return properties;     } }

@Component @ConfigurationProperties(prefix = "user") class UserConfigProperties {     String type;     String name;     Integer age;

    public String getType() {         return type;     }

    public void setType(String type) {         this.type = type;     }

    public String getName() {         return name;     }

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

    public Integer getAge() {         return age;     }

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

    @DateTimeFormat(pattern = "yyyy-MM-dd")     LocalDate birthday;

    public LocalDate getBirthday() {         return birthday;     }

    public void setBirthday(LocalDate birthday) {         this.birthday = birthday;     } } 在Nacos下,这会自动更新。 八、本地application.properties引用配置中心的参数 例如,在application.properties中添加如下: hhao.test.user.name=${user.name} 因为配置中心属性的加载顺序先于application.properteis,所以可以访问的到。

最新回复(0)