Nacos系列:基于Nacos的配置中心_知行旅人的博客-程序员资料[email protected]

技术标签: 微服务  配置中心  Spring Boot  Nacos  Spring Cloud  

前言

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

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.springfr[email protected]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上,欢迎下载学习

参考资料

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/whxaing2011/article/details/87890962

智能推荐

GNS3——建立虚拟局域网(Vlan)划分网段_Kevin Graham的博客-程序员资料

虚拟局域网(VLAN)是一种逻辑分隔的技术,能有效的防止交换网络的过量广播,相邻的端口不会接收到其他VLAN中产生的广播,节省成本,提高效率以及安全性,并且便于网络管理。建立了VLAN是否真的能起到隔离的作用呢?下面通过建立虚拟局域网来进行测试。建立虚拟局域网划分网段测试打开GNS3,把设备拖放到拓扑操作区,标记IP,VLAN等备注,设置好后打开运行设置好所有PC设备IP地址,用PC1 ..._1671465600

Java中commons-IO_ONESTAR博客的博客-程序员资料

目录一、概述二、导入 commons-io jar包1、获取 commons-io jar包2、导入 commons-io jar 包三、commons-io 的使用1、IO 工具类 FilenameUtils2、IO 工具类 FileUtils一、概述commons-IO是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方...

2020-12-30_weixin_46315812的博客-程序员资料

正式成为程序员资料专家 干勾鱼的程序员资料 08-22 2192 前几天申请的程序员资料专家成功了,从现在开始正式成为程序员资料专家,很高兴!CSDN的博客写了两年多,记录了很多技术和心得的点滴,每篇文章确实都是在用心去写。确实是好记性不如烂笔头,如...

php做个自定义限制日历,PHP开发之制作简单日历生成日历的各个边界值_成都好吃的求推荐的博客-程序员资料

自定义函数threshold方法,生成日历的各个边界值1)计算这个月总天数2)计算这个月第一天与最后一天,各是星期几3)计算日历中的第一个日期与最后一个日期...

统计学生平均成绩与及格人数_*进阶之路*的博客-程序员资料

本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数。题目保证输入与输出均在整型范围内。输入格式:输入在第一行中给出非负整数N,即学生人数。第二行给出N个非负整数,即这N位学生的成绩,其间以空格分隔。输出格式:按照以下格式输出:average = 成绩均值count = 及格人数其中平均值精确到小数点后一位。输入样例:577 54 92 73 60输出样例:average = 71.2count = 4代码:#inc.

酷比魔方iwork8刷机shell_酷比魔方iwork8旗舰版刷机教程及固件上线_带薪博士A老师的博客-程序员资料

除了这款机器所特有的采用同Suce3同样的CherryTrail芯,微软最新的系统Windows10系统,我们的产品还有以下三大特点。1.酷比魔方iwork8旗舰版是微软首家合作的8英寸windows10平板产品,系统更稳定。2.酷比魔方iwork8旗舰版采用8英寸的平板,是目前市面上能够单手握持最佳也是最大的平板范围,基于人体工程学独特设计打造的外观能够非常舒适及最大化的单手握持,实现单手通话及...

随便推点

通过按钮控制电机顺时针或逆时针旋转_perseverance52的博客-程序员资料_按键控制步进电机正反转

正反转可控的步进电机通过按钮控制电机顺时针或逆时针旋转:#include&lt;reg51.h&gt;#include&lt;string.h&gt;#include&lt;stdio.h&gt;#include&lt;intrins.h&gt;#include&lt;stdlib.h&gt;#define INT8U unsigned char#define INT16U unsigned intsbit FFW_KEY=P3^0;sbit REV_KEY=P3^1;sbit

torch自己实现交叉熵损失函数_carpediemZJ的博客-程序员资料

torch自己实现交叉熵损失函数torch实现交叉熵torch实现交叉熵import torchimport torch.nn as nnimport torch.nn.functional as Fclass Loss(torch.nn.Module): def __init__(self, reduction='mean'): super(Loss, self).__init__() self.reduction = reduction def

react学习笔记---react脚手架_苏米素的博客-程序员资料

react脚手架01-react脚手架02-创建项目并启动03-react脚手架项目结构04-功能界面的组件化编码流程(通用)一、todoList案例相关知识点配置代理react脚手架配置代理总结二、github搜索案例相关知识点01-react脚手架1.xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目1.包含了所有需要的配置(语法检查、jsx编译、devServer…)2.下载好了所有相关的依赖3.可以直接运行一个简单效果2.react提供了一个用于创建react项目的脚

python里input用法_Python中input函数的用法是什么?_许和平的博客-程序员资料

“input()”函数是输入函数,用于接受一个标准输入数据,且返回string类型。在Python3中,去除了“raw_input()”函数,仅保留了“input()”函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。1.input()函数在Python3中,input()函数接受一个标准输入数据,返回为string类型。注意:在Python3中,raw_input()和in..._1671465600

Unable to make field private final java.lang.String java.io.File.path accessible: module java.base d_杨忆的博客-程序员资料_field private final

问题:Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not “opens java.io” to unnamed module @4f3bc4f原因:JDK版本过高导致的。修改为正常的1.8即可解决方案:

学习之路uni-popup_耳朵朵朵的博客-程序员资料_uni-popup

uni-popup初次接触uniapp时用原生的js来实现弹出遮罩层的,之后了解到uni-app提供了插件uni-app 学习下来之后 着实方便很多在components中导入uni-popup组件在需要弹出层的页面中引入uni-popup使用unipopup时要在内部嵌套view 在当前view上设置弹出层的尺寸 直接在uni-popup上设置不生效uni-popup属性...

推荐文章

热门文章

相关标签