微服务中的配置管理在SpringCloud和K8S中有着不同的实现方式:
SpringCloud | K8S | |
---|---|---|
配置管理 | 配置中心(SpringCloudConfig、Nacos等) | ConfigMap、Secret等 |
下面将基于Nacos
与ConfigMap
分别介绍SpinrgCloud与K8S中配置管理的过程。
一、SpringCloud中的配置管理
(一)Nacos配置中心服务
根据Nacos官网步骤启动Nacos配置中心。
访问http://127.0.0.1:8848
进入Nacos首页。
随后在配置管理页面新建一个配置,Data ID
填写nacos-config.yaml
,配置格式勾选YAML
,配置内容编辑如下:
switch:
fun1: false
至此,一个独立于应用的远程配置已经定义好了,该配置控制了fun1这个功能的启用状态,接下来将在客户端读取此项配置以实现流程控制。
(二)配置获取与动态刷新
在pom.xml
中导入nacos-config
相关依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 新版本SpringCloud需要手动导入bootstrap以启动bootstrap.yml配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
在resources下新增bootstrap.yml
配置文件。
server:
port: 8180
spring:
application:
name: nacos-config
cloud:
nacos:
config:
file-extension: yaml
server-addr: 127.0.0.1:8848
这里之所以使用bootstrap.yml
而不是application.yaml
,是因为bootstrap优先于application加载,其配置优先级更高,保证了远程配置中心的配置永远在本地配置文件中的配置之前生效。
该文件通过server-addr
指定了nacos配置中心的地址,应用启动后,会在对应的配置中心中寻找Data ID
为nacos-config.yaml
且配置格式为YAML
的配置项(正如上述Nacos配置中心服务中配置的一样)。
SpringBoot可以使用@Value
或ConfigurationProperties
读取配置,它们本质都是读取Environment
中的值,下面将基于这两种方式分别演示Nacos配置的读取。新建入口程序如下:
@RestController
@RefreshScope
public class NacosConfigController {
// 注入Nacos配置方式一:Value
@Value("${switch.fun1:false}")
private boolean fun1Switch;
// 注入Nacos配置方式二:ConfigurationProperties
@Autowired
private FunSwitchProperties properties;
@GetMapping("/value")
public String value() {
return dealFun1(fun1Switch);
}
@GetMapping("/properties")
public String properties() {
return dealFun1(properties.getFun1());
}
private String dealFun1(boolean theSwitch) {
if (theSwitch) {
return "do fun1";
} else {
return "do nothing";
}
}
@ConfigurationProperties(prefix = "switch")
@Component
public static class FunSwitchProperties {
private boolean fun1;
public boolean getFun1() {
return fun1;
}
public void setFun1(boolean fun1) {
this.fun1 = fun1;
}
}
}
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
}
上述代码详见github
启动应用,访问服务:
curl -X GET 'http://127.0.0.1:8180/value'
curl -X GET 'http://127.0.0.1:8180/properties'
它们的响应结果都是:
do nothing
这符合预期,因为现在switch.fun1
的本地默认值和Nacos配置的值都是false
,下面,在Nacos页面修改对应的配置:
switch:
fun1: true
此时应用控制台打印如下日志,说明配置刷新成功。
Located property source: [BootstrapPropertySource {name='bootstrapProperties-nacos-config.yaml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-config,DEFAULT_GROUP'}]
再次访问服务:
curl -X GET 'http://127.0.0.1:8180/value'
curl -X GET 'http://127.0.0.1:8180/properties'
它们的响应结果变成了:
do fun1
可以看到,配置获取与动态刷新都正常运行了。
二、K8S中的配置管理
K8S的配置管理主要由ConfigMap
和Secret
组成,其中,ConfigMap
用于保存非机密性数据,Secret
则用于保存敏感数据。它们的使用方法很类似,下面以ConfigMap
为例介绍K8S的配置管理。
(一)创建ConfigMap
创建并执行configmap.yml
文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-demo
data:
key: "value"
kubectl apply -f configmap.yml
查看创建成功的ConfigMap:
kubectl get cm
kubectl describe cm configmap-demo
Name: configmap-demo
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
key:
----
value
BinaryData
====
Events: <none>
可以看到,该ConfigMap中存在了一个key-value配置,下面将在pod中使用它。
(二)使用ConfigMap实现配置获取与动态刷新
创建并执行pod.yml
文件:
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
# env方式获取configmap
env:
- name: KEY
valueFrom:
configMapKeyRef:
name: configmap-demo
key: key
# volumeMounts方式获取configmap
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
- name: config
configMap:
name: configmap-demo
kubectl apply -f pod.yml
查看Pod中的环境变量与挂载文件的值:
kubectl exec configmap-demo-pod -- env
kubectl exec configmap-demo-pod -- cat /config/key
它们key的值都是value
,说明配置的获取正常运行了。
随后,修改ConfigMap中的值:
kubectl edit cm configmap-demo
将value
修改为newvalue
,随后等待片刻,挂载的ConfigMap将会被自动更新。再次查看Pod中挂载文件的值:
kubectl exec configmap-demo-pod -- cat /config/key
可以发现,key的值已经变成了newvalue
,说明配置的动态刷新也正常运行了(需要注意的是,环境变量不会动态刷新)。
三、总结
SpringCloud通过SpringCloudConfig、Nacos等配置中心实现配置获取与动态刷新。
K8S通过ConfigMap与Secret对象实现配置获取与动态刷新。
与SpringCloud与K8S中的服务调用中类似:SpringCloud偏向于开发,而K8S则更偏向于运维。有关技术选型,需视情况而定。
参考文档
- 《深入理解SpringCloud与实战 方剑 著》
- SpringCloud官方网站
- 黑马程序员SpringCloud微服务技术栈教程
- K8S官方网站