【On Nacos】SpringCloud 方式使用 Nacos

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

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

Nacos 接入 Spring Cloud 的原始碼可以參考 spring-cloud-alibaba 這個專案,感興趣的朋友可以檢視原始碼。Spring Cloud Alibaba 的版本對應關係可以參考:版本說明 Wiki

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

配置中心

建立配置

開啟控制檯 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 Cloud 專案中獲取到 Nacos 中的配置資訊。

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

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

如果專案的 Spring Boot 版本 小於 2.4.0 需要在專案中建立 bootstrap.properties 然後在專案中的 bootstrap.properties 檔案中新增 nacos 的一些配置:

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.name=nacos-datasource
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
Spring Boot 2.4.0 版本開始預設不啟動 bootstrap 容器 本專案演示如何在 Spring boot < 2.4.0 版本使用 nacos。如果 Spring Boot 版本 ≥ 2.4.0 可以參考 **Nacos Config 2.4.x Example 進行配置

在 SpringCloud Alibaba 中,Nacos dataId 的拼接格式為:

${prefix} - ${spring.profiles.active} . ${file-extension}
  • prefix預設為spring.application.name的值,也可以通過配置項 @spring.cloud.nacos.config.prefix`來配置。
  • spring.profiles.active即為當前環境對應的 profile,詳情可以參考 Spring Boot文件

    注意,當 active profile 為空時,對應的連線符-也將不存在,dataId 的拼接格式變成${prefix}.${file-extension}
  • file-extension為配置內容的資料格式,可以通過配置項spring.cloud.nacos.config.file-extension來配置。

獲取配置

@Value 註解獲取配置

/**
 * @author lixiaoshuang
 */
@RestController
@RequestMapping(path = "springcloud/nacos/config")
public class AnnotationGetController {
    
    @Value(value = "${spring.datasource.name:}")
    private String name;
    
    @Value(value = "${spring.datasource.url:}")
    private String url;
    
    @Value(value = "${spring.datasource.username:}")
    private String username;
    
    @Value(value = "${spring.datasource.password:}")
    private String password;
    
    @Value(value = "${spring.datasource.driverClassName:}")
    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:8333/springcloud/nacos/config/annotation/get 獲取配置資訊

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

@ConfigurationProperties 註解繫結配置到類

/**
 * @author lixiaoshuang
 */
@Data
@ConfigurationProperties(prefix = "spring.datasource")
@Component
public class NacosDataSourceConfig {
    
    private String name;
    
    private String url;
    
    private String username;
    
    private String password;
    
    private String driverClassName;
}

/**
 * @author lixiaoshuang
 */
@RestController
@RequestMapping(path = "springcloud/nacos/config")
public class BindingClassController {
    
    @Resource
    private NacosDataSourceConfig nacosDataSourceConfig;
    
    
    @GetMapping(path = "binding/class/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:8333/springcloud/nacos/config/binding/class/get 獲取配置資訊

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

服務註冊&發現

服務註冊

在專案中新增以下依賴:

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

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

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.username=naocs
spring.cloud.nacos.discovery.password=nacos

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

nacos registry, DEFAULT_GROUP SPRING-CLOUD-CONFIG 192.168.1.8:8444 register finished

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

服務發現

整合 @LoadBalanced RestTemplate

首先模擬一個訂單服務的介面,可以通過服務發現的方式呼叫此介面

/**
 * @author lixiaoshuang
 */
@RestController
public class OrderServiceController {
    
    @GetMapping("/order/{orderid}")
    public String echo(@PathVariable String orderid) {
        System.out.println("接到遠端呼叫訂單服務請求");
        return "[ORDER] : " + "訂單id:[" + orderid + "] 的訂單資訊";
    }
}

先訪問下 http://localhost:8444/order/1234 獲取訂單id 為 1234 的訂單資訊,看介面是否能調通:

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

接下來在模擬一個業務介面,呼叫訂單介面。這裡通過使用 @LoadBalanced 註解使 RestTemplate 具備負載均衡和服務發現的能力,這樣就可以通過指定服務名呼叫。

/**
 * @author lixiaoshuang
 */
@RestController
public class RestTemplateController {
    
    @Autowired
    public RestTemplate restTemplate;
    
    @Bean
    @LoadBalanced
    public RestTemplate RestTemplate() {
        return new RestTemplate();
    }
    
    @GetMapping("/call/order/{orderid}")
    public String callEcho(@PathVariable String orderid) {
        // 訪問應用 SPRING-CLOUD-CONFIG 的 REST "/order/{orderid}"
        return restTemplate.getForObject("http://SPRING-CLOUD-CONFIG/order/" + orderid, String.class);
    }
}

訪問介面 http://localhost:8444/call/order/1234 獲取訂單 1234 的訂單資訊,內部將通過服務名 SPRING-CLOUD-CONFIG 發現服務,並呼叫 /order/{orderid} 介面獲取訂單資訊。

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

觀察 order 服務的日誌會發現有遠端呼叫的日誌

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