1. 程式人生 > 程式設計 >Spring Cloud Alibaba Nacos Config

Spring Cloud Alibaba Nacos Config

前言

前面我們學習瞭如何在Spring Boot中使用Nacos來管理配置,整體來說還是比較簡單。

為了能夠在Spring Cloud中更加方便的使用Nacos,今天介紹下在Spring Cloud中如何簡單,快速,方便的使用Nacos。

使用

需要在專案中加入spring-cloud-starter-alibaba-nacos-config的Maven依賴。

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Greenwich.SR2</version>
			<type
>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>0.9.0.RELEASE</version> </dependency> </dependencies> 複製程式碼

版本選擇請參考下面的規範:

由於 Spring Boot 1 和 Spring Boot 2 在 Actuator 模組的介面和註解有很大的變更,且 spring-cloud-commons 從 1.x.x 版本升級到 2.0.0 版本也有較大的變更,因此我們採取跟 SpringBoot 版本號一致的版本:

1.5.x 版本適用於 Spring Boot 1.5.x 2.0.x 版本適用於 Spring Boot 2.0.x 2.1.x 版本適用於 Spring Boot 2.1.x

在bootstrap.properties中配置Nacos的資訊,切記是bootstrap.properties不是application.properties,原因你可以自己體驗下。

# 應用名稱,用於配置檔案命名
spring.application.name=example
# Nacos server 的地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 配置內容的資料格式
spring.cloud.nacos.config.file-extension=properties
# 指定對應的環境
spring.profiles.active=test
複製程式碼

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profile.active}.${file-extension}
複製程式碼

prefix 預設為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。

然後我們在Nacos的後臺建立一個配置,dataId為example-test.properties

useLocalCache=false
複製程式碼

再建立一個example-dev.properties

useLocalCache=true
複製程式碼

測試程式碼:

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }

}
複製程式碼

配置變更需要重新整理的話記得加上@RefreshScope註解。載入對應環境的配置是根據spring.profiles.active=test的值進行載入,當我們指定test後,useLocalCache的值為false,當spring.profiles.active=dev時,useLocalCache的值為true

方便的點在於不用啟動時指定namespace來區分環境,而是跟Spring Boot中的spring.profiles.active進行了整合。

多Data-Id的使用

如果我們需要載入多個配置檔案,可以用ext-config來配置

spring.cloud.nacos.config.ext-config[0].data-id=app.properties
spring.cloud.nacos.config.ext-config[0].group=multi-data-ids
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=user.properties
spring.cloud.nacos.config.ext-config[1].group=multi-data-ids
spring.cloud.nacos.config.ext-config[1].refresh=true
複製程式碼

nacos-config端點

spring-cloud-starter-alibaba-nacos-config內建了nacos-config端點,可以通過nacos-config端點檢視配置相關資訊,原始碼在org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigEndpoint

{
  "NacosConfigProperties": {
    "serverAddr": "127.0.0.1:8848","encode": null,"group": "DEFAULT_GROUP","prefix": null,"fileExtension": "properties","timeout": 3000,"endpoint": null,"namespace": null,"accessKey": null,"secretKey": null,"contextPath": null,"clusterName": null,"name": null,"sharedDataids": null,"refreshableDataids": null,"extConfig": [
      {
        "dataId": "example.properties","refresh": true
      },{
        "dataId": "student.properties","refresh": true
      }
    ]
  },"RefreshHistory": [],"Sources": [
    {
      "lastSynced": "2019-08-18 13:07:42","dataId": "student.properties"
    },{
      "lastSynced": "2019-08-18 13:07:42","dataId": "null-test.properties"
    },"dataId": "null.properties"
    },"dataId": "example.properties"
    }
  ]
}
複製程式碼

NacosConfigHealthIndicator

spring-cloud-starter-alibaba-nacos-config內建了Nacos健康狀態檢查的實現,當Nacos出現故障時,能夠及時通過actuator/health進行反饋,原始碼在org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigHealthIndicator


  "status": "UP","details": {
    "diskSpace": {
      "status": "UP","details": {
        "total": 249795969024,"free": 12436131840,"threshold": 10485760
      }
    },"nacosConfig": {
      "status": "UP","details": {
        "dataId: 'student.properties',group: 'DEFAULT_GROUP'": "config is empty","dataId: 'null-test.properties',"dataId: 'null.properties',"dataId: 'example.properties',"dataIds": [
          "student.properties","null-test.properties","null.properties","example.properties"
        ]
      }
    },"refreshScope": {
      "status": "UP"
    }
  }
}
複製程式碼

目前我自己看下來,感覺這塊有那麼一點點問題,現象是Nacos服務全部停掉之後,Nacos的health狀態還是UP,並不是我們期望的DOWN。

看了下原始碼,發現了原因,在最後一行設定了UP資訊,就算前面設定了DOWN,最後都會變成UP,不知道這是不是BUG,哈哈。。。

@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
	for (String dataId : dataIds) {
		try {
			String config = configService.getConfig(dataId,nacosConfigProperties.getGroup(),nacosConfigProperties.getTimeout());
			if (StringUtils.isEmpty(config)) {
				builder.down().withDetail(String.format("dataId: '%s',group: '%s'",dataId,nacosConfigProperties.getGroup()),"config is empty");
			}
		}
		catch (Exception e) {
			builder.down().withDetail(String.format("dataId: '%s',e.getMessage());
		}
	}
    // 問題出在這邊
	builder.up().withDetail("dataIds",dataIds);
}
複製程式碼

我覺得最後一行應該加一個判斷,當前面已經設定DOWN的時候,這邊就不要再設定成UP了

if( builder.build().getStatus() != Status.DOWN ) {
	builder.up().withDetail("dataIds",dataIds);
}
複製程式碼

這邊改完之後,還是有個問題,就是Nacos其實在本地也有快取配置資訊,當然這個失效時間我沒去看程式碼,還不知道多久失效。也就是說當Nacos所有的服務都掛掉後,這邊也不能及時將健康狀態設定成DOWN,因為configService.getConfig的時候,內部會優先從本地快取中獲取配置,所以配置是可以獲取到的,也就是健康檢查在這種情況下是無效的。

我個人感覺健康檢查既然要做的話,那麼就不要走這個邏輯,最簡單的方式每次直接從Nacos服務讀取,讀取異常這個時候就可以設定成DOWN,就是這麼簡單。

不說了,去Github提個issues問問大佬們....

猿天地