【On Nacos】SpringBoot 方式使用 Nacos

曉雙 發表於 2022-07-02
Spring

如果大家想要了解更多的 Nacos 教程,歡迎 star 《On Nacos》開源專案。基於 Nacos 2.x 的入門、原理、原始碼、實戰介紹,幫助開發者快速上手 Nacos。

本文介紹下如何在 Spring Boot 專案中使用 Nacos,Nacos 主要分為兩個部分,配置中心和服務註冊與發現。在使用 Spring Boot 專案中使用 Nacos ,首先要保證啟動一個 Nacos 服務,具體可以參考【快速上手 Nacos】來搭建一個單機的 Nacos 服務。

Nacos 封裝 starter 的原始碼可以參考 【nacos-spring-boot-project】 這個專案,感興趣的朋友可以檢視原始碼。

本篇文章的詳細的程式碼示例點選【nacos-spring-boot】檢視

配置中心

建立配置

開啟控制檯 http://127.0.0.1:8848/nacos ,進入 配置管理-配置列表 點選+號新建配置,這裡建立個資料來源配置例子: nacos-datasource.yaml

spring:
    datasource:
     name: datasource
     url: jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useDynamicCharsetInfo=false&useSSL=false
     username: root
     password: root
     driverClassName: com.mysql.jdbc.Driver

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kow3r2tkj21680u0wgu.jpg

新增依賴

配置建立好就可以在控制檯 配置管理-配置列表中檢視到。接下來演示下怎麼在 Spring Boot 專案中獲取到 Nacos 中的配置資訊。

需要在專案中新增以下依賴:

<!--配置中心 starter-->
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>nacos-config-spring-boot-starter</artifactId>
    <version>${latest.version}</version>
</dependency>

然後在專案中的 application.properties 檔案中新增 nacos 的一些配置:

nacos.config.server-addr=127.0.0.1:8848
nacos.config.group=DEFAULT_GROUP
nacos.config.namespace=
nacos.config.username=nacos
nacos.config.password=nacos

獲取配置

繫結到類獲取

可以通過 @NacosConfigurationProperties 註解將 nacos-datasource.yaml 中的配置繫結到 NacosDataSourceConfig 類上。這樣就可以通過 @Resource@Autowired 將 NacosDataSourceConfig 注入到要使用的地方。

@NacosConfigurationProperties(prefix = "spring.datasource", dataId = "nacos-datasource.yaml", autoRefreshed = true)
@Component
@Data
public class NacosDataSourceConfig {
    
    private String name;
    
    private String url;
    
    private String username;
    
    private String password;
    
    private String driverClassName;
}

建立一個 Controller ,寫一個獲取配置資訊的介面:

/**
 * @author lixiaoshuang
 */
@RestController
@RequestMapping(path = "springboot/nacos/config")
public class NacosConfigController {
    
    @Resource
    private NacosDataSourceConfig nacosDataSourceConfig;
    
    @GetMapping(path = "get")
    private Map<String, String> getNacosDataSource() {
        Map<String, String> result = new HashMap<>();
        result.put("name", nacosDataSourceConfig.getName());
        result.put("url", nacosDataSourceConfig.getUrl());
        result.put("username", nacosDataSourceConfig.getUsername());
        result.put("password", nacosDataSourceConfig.getPassword());
        result.put("driverClassName", nacosDataSourceConfig.getDriverClassName());
        return result;
    }
}

然後啟動服務,訪問 http://localhost:8080/springboot/nacos/config/binding/class/get 就可以獲取到對應的配置資訊:

https://tva1.sinaimg.cn/large/e6c9d24ely1h3koknj05gj21zm0hujv1.jpg

@[email protected] 註解獲取

在建立一個 properties 格式的配置,演示下使用 @NacosValue + @NacosPropertySource 註解獲取配置資訊。還是開啟 配置管理-配置列表 點選+號新建配置:nacos-datasource.properties

name=datasource
url=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useDynamicCharsetInfo=false&useSSL=false
username=root
password=root
driverClassName=com.mysql.jdbc.Driver

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kounqdmsj216m0u0wgp.jpg

通過 @NacosValue + @NacosPropertySource 註解獲取指定 dataId 的配置

/**
 * @author lixiaoshuang
 */
@RestController
@RequestMapping(path = "springboot/nacos/config")
@NacosPropertySource(dataId = "nacos-datasource.properties", autoRefreshed = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)
public class AnnotationGetController {
    
    @NacosValue(value = "${name:}", autoRefreshed = true)
    private String name;
    
    @NacosValue(value = "${url:}", autoRefreshed = true)
    private String url;
    
    @NacosValue(value = "${username:}", autoRefreshed = true)
    private String username;
    
    @NacosValue(value = "${password:}", autoRefreshed = true)
    private String password;
    
    @NacosValue(value = "${driverClassName:}", autoRefreshed = true)
    private String driverClassName;
    
    @GetMapping(path = "annotation/get")
    private Map<String, String> getNacosDataSource2() {
        Map<String, String> result = new HashMap<>();
        result.put("name", name);
        result.put("url", url);
        result.put("username", username);
        result.put("password", password);
        result.put("driverClassName", driverClassName);
        return result;
    }
}

訪問 http://localhost:8080/springboot/nacos/config/annotation/get 獲取 nacos-datasource.properties 的配置資訊:

https://tva1.sinaimg.cn/large/e6c9d24ely1h3koyy2gw9j21z00gu77r.jpg

配置監聽

Spring Boot 的使用方式也可以通過 @NacosConfigListener 註解進行配置變更的監聽,在建立一個 hello-nacos.text 配置:

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kpuvham9j219k0u0dhh.jpg

/**
 * @author lixiaoshuang
 */
@Component
public class ConfigListener {
    
    /**
     * 基於註解監聽配置
     *
     * @param newContent
     * @throws Exception
     */
    @NacosConfigListener(dataId = "hello-nacos.text", timeout = 500)
    public void onChange(String newContent) {
        System.out.println("配置變更為 : \n" + newContent);
    }
    
}

然後在將 hello-nacos.text 的配置內容修改為 ” hello nacos config “,程式碼中就會回撥 onChange() 方法

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kpz4de68j210q0gomy4.jpg

服務註冊&發現

服務註冊

在專案中新增以下依賴:

<!--註冊中心 starter-->
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>nacos-discovery-spring-boot-starter</artifactId>
    <version>${latest.version}</version>
</dependency>

然後在專案中的 application.properties 檔案中新增 nacos 的一些配置:

nacos.discovery.server-addr=127.0.0.1:8848
nacos.discovery.auto-register=true
nacos.discovery.register.clusterName=SPRINGBOOT
nacos.discovery.username=nacos
nacos.discovery.password=nacos

當新增完配置以後,並且開啟了自動註冊,啟動服務以後看到下面這段日誌,就說明服務註冊成功了。

Finished auto register service : SPRING_BOOT_SERVICE, ip : 192.168.1.8, port : 8222

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kx59muggj22l30u04dq.jpg

服務發現

可以使用 Nacos 提供的 NacosNamingService 來獲取到服務的例項,可以通過 @NacosInjected 註解將 NacosNamingService 注入到需要使用的地方。

/**
 * @author lixiaoshuang
 */
@RestController
@RequestMapping(path = "springboot/nacos/discovery")
public class NacosDiscoveryController {
    
    @NacosInjected
    private NacosNamingService nacosNamingService;
    
    @RequestMapping(path = "get")
    public List<Instance> getInfo(@RequestParam("serviceName") String serviceName) throws NacosException {
        return nacosNamingService.getAllInstances(serviceName);
    }
}

通過呼叫 http://localhost:8222/springboot/nacos/discovery/get?serviceName=SPRING_BOOT_SERVICE 獲取 SPRING_BOOT_SERVICE 服務的例項資訊。

https://tva1.sinaimg.cn/large/e6c9d24ely1h3kxi7wg4nj21rq0r2aed.jpg