前言

在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式:

1、硬编码

没有什么配置不配置的,直接写在代码里面,比如使用常量类

优势:对开发友好,开发清楚地知道代码需要用到什么配置

劣势:涉及秘钥等敏感配置直接暴露给开发人员,不安全;如果想修改配置必须重新发版,比较麻烦

2、外部化配置文件

Spring项目经常会在resoures目录下放很多配置文件,各个环境对应不同的配置文件,通过SVN管理

优势:配置文件外部化,支持多环境配置管理,修改配置只需重启服务,无需发版

劣势:系统庞大时,配置文件很多,多人开发,配置格式不统一,维护麻烦;敏感配置不需要暴露给开发人员,降低风险,但开发经常要和运维沟通怎么修改配置,沟通不恰当容易引发生产事故;而且,如果应用部署在多台机器,对运维来说,修改配置也是非常头疼的事情(当然也可以引入NFS系统来解决一部分问题)

3、数据库

配置信息存储在数据库中,灵活修改

优势:可以灵活管理配置,无需重启服务

劣势:界面不友好,配置没有版本管理,一旦出现问题,回滚或定位问题都比较麻烦;此外,数据库必须要保证高可用,避免因此而造成生产故障

4、配置中心

微服务基础架构体系中的一个不可或缺的基础组件

优势:集中化管理,敏感配置可控;多版本存储,方便追溯;界面友好,修改配置一键发布;即使面对多集群也能从容应对,十分淡定

劣势:引入组件,增加系统风险;如果是中途切换成配置中心,也会增加研发接入成本;配置中心也需要保证高可用,否则容易造成大面积影响

以上几种管理配置文件的方式,我想都会有公司在用,不要因为配置中心有诸多优点,就盲目引进项目中,我觉得应该遵守以下两个原则:

  • 做人做事,要知道自己几斤几两

释义:没深入研究过的技术,就不要随便拿到公司项目中来试水啦,恐怕到时候坑够你填的,要不然就是你有信心玩得转它。

  • 杀只鸡而已,你拿牛刀来做甚?

释义:小团队小项目选择简单的配置管理方式就好了,要什么配置中心,纯属没事找事。

总而言之,我们必须从实际出发,实事求是,选择适合自己的技术栈。

关于为什么需要有配置中心,我推荐一篇文章给你看,讲得比较透彻:《微服务架构为什么需要配置中心?》

另外,我觉得对开发本身来说,是宁愿自己管理自己代码的配置的,交给运维总是会有各种各样的问题,至于敏感配置,说实话,开发人员要真想做点“坏事”,那拦得住吗?但是,从公司的角度来讲,把服务器的配置管理交给运维同事是符合常理的,系统需要稳定且安全地运行,这是对客户的负责,从这一方面去思考,这么做是合情合理的。

Okay,我就啰嗦到这里吧,下面正式介绍Nacos作为配置中心是怎么使用的。

Nacos 结合 Spring

添加 maven 依赖:

<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${nacos-spring-context.version}</version>
</dependency>

使用 @EnableNacosConfig 开启 Nacos Spring 的配置管理功能

@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
@NacosPropertySource(dataId = "nacos.spring.config", autoRefreshed = true)
public class NacosConfig {
}

其中:

@Configuration:Spring的注解,配置应用上下文
@EnableNacosConfig:Nacos的注册,启用 Nacos Spring 的配置管理服务
@NacosProperties:全局和自定义Nacos属性的统一注解
@NacosPropertySource:加载数据源
globalProperties:全局 Nacos 属性
serverAddr:Nacos Server服务器地址
dataId:配置的数据集ID
autoRefreshed:是否开启配置动态更新

再写一个Controller类,来验证Nacos的配置管理功能,代码如下:

package com.learn.nacos;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
@RequestMapping(value = "config")
public class NacosConfigController {
@NacosInjected
private ConfigService configService; @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
private boolean useLocalCache; @RequestMapping(value = "/get", method = RequestMethod.GET)
@ResponseBody
public boolean get() {
return useLocalCache;
} @RequestMapping(method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> publish(@RequestParam String dataId,
@RequestParam(defaultValue = "DEFAULT_GROUP") String group,
@RequestParam String content) throws NacosException {
boolean result = configService.publishConfig(dataId, group, content);
if (result) {
return new ResponseEntity<String>("Success", HttpStatus.OK);
}
return new ResponseEntity<String>("Fail", HttpStatus.INTERNAL_SERVER_ERROR);
}
}

该Controller类提供了两个HTTP接口

读取配置:http://127.0.0.1:8080/config/get

发布配置:http://127.0.0.1:8080/config?dataId=XXX&content=XXX

发布配置还可以通过 Nacos Open API:curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=XXX&group=XXX&content=XXX 发布配置,你也可以用Postman工具模拟POST请求进行配置发布,我这里主要是为了方便验证问题,采用了这种方式。

在验证之前,请先确保 Nacos Server 已经启动,Nacos Server 的安全及启动方式详见:《Nacos系列:欢迎来到Nacos的世界!》

启动Tomcat,观察Console控制台

20:50:13.646 [RMI TCP Connection(5)-127.0.0.1] WARN com.alibaba.nacos.spring.core.env.AnnotationNacosPropertySourceBuilder - There is no content for NacosPropertySource from dataId[nacos.spring.config] , groupId[DEFAULT_GROUP] , properties[{encode=${nacos.encode:UTF-8}, namespace=${nacos.namespace:}, contextPath=${nacos.context-path:}, endpoint=${nacos.endpoint:}, serverAddr=${nacos.server-addr:}, secretKey=${nacos.secret-key:}, accessKey=${nacos.access-key:}, clusterName=${nacos.cluster-name:}}].

20:50:17.825 [RMI TCP Connection(5)-127.0.0.1] INFO com.alibaba.nacos.spring.context.event.LoggingNacosConfigMetadataEventListener - Nacos Config Metadata : dataId='nacos.spring.config', groupId='DEFAULT_GROUP', beanName='nacosConfig', bean='null', beanType='class com.learn.nacos.NacosConfig', annotatedElement='null', xmlResource='null', nacosProperties='{serverAddr=127.0.0.1:8848, encode=UTF-8}', nacosPropertiesAttributes='{encode=${nacos.encode:UTF-8}, namespace=${nacos.namespace:}, contextPath=${nacos.context-path:}, endpoint=${nacos.endpoint:}, serverAddr=${nacos.server-addr:}, secretKey=${nacos.secret-key:}, accessKey=${nacos.access-key:}, clusterName=${nacos.cluster-name:}}', source='org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor@66e4d430', timestamp='1550753413647'

我们先通过http://127.0.0.1:8080/config?dataId=nacos.spring.config&content=useLocalCache=true发布一个dataId为nacos.spring.config且配置内容为useLocalCache=true的配置集,观察Nacos控制台的变化

再通过http://127.0.0.1:8080/config/get读取配置

然后在Nacos控制台将useLocalCache的值改为false,并发布配置

再次访问http://127.0.0.1:8080/config/get

Nacos 结合 Spring Boot

添加 Starter 依赖:

<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.1</version>
</dependency>

注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。

application.properties中添加如下配置信息:

nacos.config.server-addr=127.0.0.1:8848

添加NacosConfigApplication启动类

@SpringBootApplication
@NacosPropertySource(dataId = "nacos.springboot.config", autoRefreshed = true)
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
}

如果你看过我的上一篇文章:《Nacos系列:基于Nacos的注册中心》,那么你应该知道 Spring Boot 实现方式和 Spring 的没太大差别,所以我就不再细说了,请参考我的源码示例或者官网资料学习。

这里说下我在学习过程中遇到的一个问题,在application.properties添加配置文件的时候,不小心将nacos.config.server-addr写成了nacos.discovery.server-addr,结果启动项目时,一直报错:

ERROR 9028 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

------

APPLICATION FAILED TO START

------

Description:

client error: invalid param. null

Action:

please check your client configuration

刚开始一直找不到原因,后面跟着官网代码示例复核,才发现是配置问题导致的,呵呵哒,自己给自己挖坑。

后语

我挺喜欢Nacos的,既然做服务发现和管理,又能做配置管理,这两者本质没多大区别,Nacos把这两者统一起来,一举两得,我觉得没什么不好,要不然你引入了Zookeeper作为注册中心,还要引入Apollo作为配置中心,无端增加学习成本。就像之前听音乐,我一般用网易云音乐就好,后面因为搞了版权的事,不得不下载了虾米和QQ音乐,我就听个歌而已,手机里装了三个APP,你说,这叫什么事儿?

示例源码

  • Nacos + Springlearn-nacos-spring-config
  • Nacos + Spring Bootlearn-nacos-springboot-config

代码已上传至码云Github上,欢迎下载学习

参考资料

最新文章

  1. js实现一个简单计算器
  2. Codeforces Round #172 (Div. 2)
  3. yii 图片展示
  4. linux(本机)配置域名
  5. QT读写ini配置文件
  6. centos7中 npm install express 时Error: Cannot find module &#39;express&#39;错误
  7. Swagger使用总结
  8. gitbook使用
  9. Openstack os-networks API create network 方法
  10. [原创作品]web网页中的锚点
  11. 【DFS+小操作判重】【HDU2610+HDU2611】Sequence
  12. RGB HSV HLS三种色彩模式转换(C语言实现)
  13. java读取Excel文档插入mysql
  14. 第三方登录SDK
  15. IOS UITextView自适应高度
  16. Bootstrap3 表单-被支持的控件:文本域
  17. java的编译过程
  18. appium 使用环境安装配置记录
  19. CentOS中/英文环境切换教程(CentOS6.8)
  20. root用户以修改文件的方式,修改用户密码

热门文章

  1. Python 获取车票信息
  2. 分享几个写 demo 的思路
  3. 使用vmware vconverter从物理机迁移系统到虚拟机P2V(多图)
  4. windows和ubuntu下git commit提交后如何保存和退出,回到命令行
  5. homekit2mqtt on DietPi
  6. Py福利,基于uiautomatorviewer 的Python 自动化代码自动生成工具分享(jar已发布GitHub,欢迎Star)
  7. vscode配置git及码云
  8. Visual Studio 常见的快捷键
  9. 微信 SQLite 数据库修复实践
  10. 包建强的培训课程(1):Android App企业级开发