前言

前面我们学习了如何在Spring Boot中使用Nacos来管理配置,整体来说还是比较简单。

为了能够在Spring Cloud中更加方便的使用Nacos,今天介绍下在Spring Cloud中如何简单,快速,方便的使用Nacos。

使用

需要在项目中加入spring-cloud-starter-alibaba-nacos-config的Maven依赖。








org.springframework.cloud



spring-cloud-dependencies



Greenwich.SR2



pom



import







org.springframework.boot



spring-boot-starter-parent



2.1.6.RELEASE



pom



import











org.springframework.boot



spring-boot-starter-web







org.springframework.cloud



spring-cloud-starter-alibaba-nacos-config



0.9.0.RELEASE



版本选择请参考下面的规范:

由于 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进行了整合。这样的方式还是只有默认的namespace,只不过是通过data-id的命名规则来区分环境。

多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"
,

"group"
:

"DEFAULT_GROUP"
,

"refresh"
:

true

},

{

"dataId"
:

"student.properties"
,

"group"
:

"DEFAULT_GROUP"
,

"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"

},

{

"lastSynced"
:

"2019-08-18 13:07:42"
,

"dataId"
:

"null.properties"

},

{

"lastSynced"
:

"2019-08-18 13:07:42"
,

"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', group: 'DEFAULT_GROUP'"
:

"config is empty"
,

"dataId: 'null.properties', group: 'DEFAULT_GROUP'"
:

"config is empty"
,

"dataId: 'example.properties', group: 'DEFAULT_GROUP'"
:

"config is empty"
,

"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', group: '%s'"
,
                    dataId
,
 nacosConfigProperties
.
getGroup
()),
 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问问大佬们....
Spring Cloud Alibaba 整合Nacos Config_第1张图片
尹吉欢