Nacos配置中心落地与实践

2023-11-17

一、背景

目前,我们公司各团队配置中心使用各异,电商使用的是 Spring Cloud Config,支付使用的是 Apollo,APP 团队使用的是 Apollo+Nacos。为了更好地应对公司业务的发展,统一基础设施技术栈必不可少。

image-20220222140242719

图片来源:直播《如何做好微服务基础设施选型》–李运华

此外,电商团队使用的 Spring Cloud Config 面临以下技术痛点:

  • 修改配置需要重启服务
  • 配置管理不友好(通过gitlab修改)
  • 缺少权限管控、格式检验、安全配置等特性

二、配置中心选型

开源产品分析

  • Spring Cloud Config

2014年9月开源,Spring Cloud 生态组件,可以和 Spring Cloud 体系无缝整合。

  • Apollo

2016年5月,携程开源的一款可靠的分布式配置管理中心。能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

  • Nacos

2018年6月,阿里开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。

比较项 Nacos Apollo Spring Cloud Config
社区活跃度 开源时间 2018.6 2016.5 2014.9
github关注 20.5k 26K 1.7K
文档 完善 完善 完善
性能 单机读(QPS) 15000 9000 7(限流所致)
单机写(QPS) 1800 1100 5(限流所致)
可用性 停服影响(配置服务) 已启动的客户端不影响 已启动的客户端不影响 已启动的客户端不影响
部署模式 集群 集群 集群
易用性 配置生效时间 实时 实时 重启生效,或手动refresh生效
数据一致性 HTTP异步通知 数据库模拟消息队列,Apollo定时读消息 一分钟实时生效 Git保证数据一致性,Config-server从Git读数据
配置界面 支持 支持 不支持
配置格式校验 支持 支持 不支持
配置回滚 支持 支持 支持(基于git的回滚)
版本管理 支持 支持 支持(基于git的版本管理)
客户端支持语言 官方java 非官方 Go、Python、NodeJS、C++ 官方java .net 非官方 Go、Python、NodeJS、PHP、C++
客户端使用 nacos client apollo client cloud config client
安全性 权限管理 支持 完善 数据权限都比较完善 支持(git)
授权/审计/审核 支持 界面上直接操作且支持修改和发布权限分离 依赖git权限管理
数据加密 不支持 不支持 加密和解密属性值
架构复杂度 运维成本 Nacos+MySQL(部署简单) Config+Admin+Portal+MySQL(部署复杂) Config-server+Git+MQ(部署复杂)
服务依赖 自身就是注册发现中心 阿里云两个功能隔开了 分布式 需要注册中心 内置了eureka 需要注册中心
灰度发布 支持 客户端配置 且路由规则客户端计算 耦合高 繁琐 支持 服务端配置 且路由规则服务端计算 客户端透明 简单 支持
邮件服务 不支持 支持 不支持
查询配置监听 支持 支持 支持
  1. 从性能方面看:读写性能 Nacos > Apollo > Spring Cloud Config。
  2. 从功能方面看:功能完善度 Apollo > Nacos > Spring Cloud Config。
  3. 从社区活跃性看:原来Spring Cloud 那一套生态Netflix基本上不怎么维护了,因为不赚钱;但是 Spring Alibaba 这套微服务生态会一直开源且有维护,因为阿里将这一块 SaaS 化后赚钱。
  4. Nacos的优势:简单。它整合了注册中心、配置中心功能,部署和操作相比Apollo都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。

性能对比

  • 压力机信息

处理器:Intel® Core™ i5-9500 CPU @ 3.00GHz 3.00 GHz

系统:window 10

内测:16G

  • 压测工具:JMeter
  • 压测策略:100用户请求线程 10内递增开启,持续时间100s

场景一:调用服务端

image-20220222142033442

测试结果如下:

image-20220222142102625

通过压测发现,Nacos读配置的TPS大约是11000左右 ,写配置TPS大约是1800左右,而Apollo读配置TPS大约是1100,写配置TPS大约310,Nacos读写性能优势非常明显。

场景二:调用客户端

image-20220222142123826

测试结果如下:

image-20220222142232508

可见,读性能相差不大。

结论

选择的原因 不选择的原因
Nacos 统一技术栈能解决现有技术痛点运维成本低
Apollo 依赖 Eureka
Spring Cloud Config

参考文档:

三、快速使用

参考文档:https://nacos.io/en-us/docs/quick-start-spring-boot.html

升级依赖

去除 spring-cloud-config 依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

添加 Nacos 依赖:

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

替换 Nacos 配置

将原 bootstrap.yml 文件中的 config 配置替换成 nacos 的配置。

spring:
  application:
    name: {应用名}
  cloud:                                                      # 移除
    config:                                                   # 移除
      uri: http://config-center.alpha-intra.dbses.com/conf    # 移除
      label: alpha                                            # 移除

替换结果如下:

spring:
  application:
    name: {应用名}
nacos:
  config:
    server-addr: http://ec-nacos.dbses.com
    namespace: alpha
    group: {组名}

启动类添加注解

// dataId 对应服务的配置
@NacosPropertySource(groupId = "${nacos.config.group}", dataId = "${spring.application.name}.yml", first = true)
public class WebApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
 
}

四、实践

配置动态刷新

方式一:使用@NacosValue

使用此种方法需要在@NacosPropertySource 需加上 autoRefreshed=true。示例代码如下:

@NacosPropertySource(groupId = "infra", dataId = "zebra-service.yml", first = true, autoRefreshed = true)
public class WebApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
 
}

nacos 配置如下:

test1:
  config: 2

接口代码如下:

@RestController
public class TestController {
 
    @NacosValue(value = "${test1.config}", autoRefreshed = true)
    private String config;
 
    @GetMapping("/config")
    public String getConfig() {
        return config;
    }
 
}

方式二:使用@NacosConfigurationProperties

示例代码如下:

@Configuration
@Data
@NacosConfigurationProperties(prefix = "test2", dataId = "zebra-service.yml", groupId = "infra", autoRefreshed = true)
public class TestConfig {
 
    private List<String> config;
 
    private Map<String, String> map;
 
    @Override
    public String toString() {
        return "TestConfig{" + "config=" + config + ", map=" + map + '}';
    }
 
}

nacos 配置如下:

test2:
  config:
    - yang
    - wang
  map:
    courier: yang
    zebra: wang

接口代码如下:

@RestController
public class TestController {
 
    @Autowired
    private TestConfig testConfig;
 
    @GetMapping("/config2")
    public String getConfig2() {
        return testConfig.toString();
    }
 
}

注意

动态刷新map,修改了key会累加,不会删除原来的key。例如将 zebra-service.yml 配置中的 test2.map.zebra 改为 test2.map.zebr 后,获取的结果如下:

TestConfig{config=[yang, wang], map={courier=yang, zebra=wang, zebr=wang}}

方式三:使用@NacosConfigListener

nacos 配置如下:

test1:
  config: 2

示例代码如下:

@RestController
public class TestController {
 
    @Value(value = "${test1.config}")
    private String config;
 
    @GetMapping("/config")
    public String getConfig() {
        return config;
    }
 
    @NacosConfigListener(dataId = "zebra-service.yml", groupId = "infra")
    public void testConfigChange(String newContent) {
        YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
        yamlFactory.setResources(new ByteArrayResource(newContent.getBytes()));
        Properties commonsProperties = yamlFactory.getObject();
        this.config = commonsProperties.getProperty("test1.config"));
    }
 
}

多配置引入

问题描述

我们的项目之前读取了许多公共配置,现想要读取公共配置,该怎么办?

问题解决

使用 @NacosPropertySources 注解即可加入多个配置文件。

样例代码:

@NacosPropertySources({
        @NacosPropertySource(groupId = "infra", dataId = "captcha-service.yml", first = true),
        @NacosPropertySource(groupId = "commons", dataId = "__common_eureka_.yml")
})
public class WebApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
 
}

这里的 first = true 表示这个文件的配置优先级是最高的。

本地配置覆盖

问题描述

作为开发人员,我们可能需要本地启动程序来进行调试,但此时本地启动的程序连接的是 alpha 环境的配置。如果修改 alpha 环境的配置,又可能影响 alpha 及其他人的程序运行。

面对这种情况,我们怎么管理配置的优先级?

下面以 test1.config 配置为例。nacos 配置文件如下:

image-20220222143101832

启动配置如下:

image-20220222143133401

测试代码如下:

@RestController
public class TestController {
 
    @NacosValue(value = "${test1.config}", autoRefreshed = true)
    private String config1;
 
    @GetMapping("/config1")
    public String getConfig1() {
        return config1;
    }
}

执行结果为:

image-20220222143208909

本地的配置并没有达到覆盖的效果。

问题分析

我们不妨先改造一下程序启动类。

image-20220222143652521

通过断点可以看到,应用配置(这里指 nacos 中的 zebra-service.yml,下同)的优先级是在公共配置之前的,这点是必要的。

应用配置必须在公共配置之前。

但是应用配置也在系统变量(systemProperties)、系统环境(systemEnvironment)之前。所以我们配置的 test1.config 并没有生效为 local。

稍作修改一下:

image-20220222143612121

问题解决

再测试一下本地配置是否覆盖。

image-20220222143742655

本地的配置已达到覆盖的效果。最终的启动类代码为:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@PrepareConfigurations({"__common_database_", "__common_eureka_"})
@NacosPropertySource(groupId = "infra", dataId = "zebra-service.yml", autoRefreshed = true
        ,after = StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME
)
public class WebApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
 
}

本文由博客一文多发平台 OpenWrite 发布!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nacos配置中心落地与实践 的相关文章

  • [Python系列-8]:Python之人工智能 - 基本工具 -2- 随机数生成库

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https mp csdn net mp blog creation editor 119254076 目录 1 什么需要随机数生成
  • Echarts的tooltip显示自定义格式化解决方案

    前言 今天甲方爸爸提出了要求 需要把图表显示的数据保留百分数的小数点后一位 实际上这个显示的问题之前在后台处理数据的时候就处理过 当时是没有保留小数的 后来要求保留小数点后一位就在后台处理了 谁知道 在前台展示的时候 莫名的出现小数点后十几
  • 大数据分析R中泊松回归模型实例

    如果您知道如何以及何时使用泊松回归 它可能是一个非常有用的工具 在大数据分析R中泊松回归模型实例中 我们将深入研究泊松回归 它是什么以及R程序员如何在现实世界中使用它 具体来说 我们将介绍 1 泊松回归实际上是什么 什么时候应该使用它 2
  • Shell重定向 &>file、2>&1、1>&2 、/dev/null的区别

    在shell脚本中 默认情况下 总是有三个文件处于打开状态 标准输入 键盘输入 标准输出 输出到屏幕 标准错误 也是输出到屏幕 它们分别对应的文件描述符是0 1 2 gt 默认为标准输出重定向 与 1 gt 相同 2 gt 1 意思是把 标
  • 下载xlsx中的URL到指定目录

    爱情是灯 友情是影子 当灯灭了 你会发现你的周围都是影子 朋友 是在最后可以给你力量的人 import org apache poi ss usermodel import org apache poi xssf usermodel XSS

随机推荐

  • KVM更改虚拟机默认存储路径

    Virt默认的虚拟机存储路径是 var lib libvirt images 如下图所示 接下来我们创建一个新的存储池 用来存储新建的虚拟机 存储池的名称为vm 路径为 usr local src kvm 新的存储池已创建成功 接下来新建虚
  • 数字IC设计知识点及综合题详解(提前批、秋招必刷基础题)——(二)时序分析基础(Slack、Setup、Hold、Jitter、Skew、亚稳态)异步复位,同步释放

    目录 一 常见名词 1 1 时钟偏移Skew 1 1 1 Skew出现的原因 1 1 2 Skew解决方法 1 2 抖动Jitter 1 2 1 Jitter出现的原因 1 2 2 时钟抖动永远存在 1 3 扇入扇出Fan in Fan o
  • 【最新最详细】SQL Server 2019 安装教程

    最新最详细 SQL Server 2019 安装教程 引言 今天又双叒搞新电脑的环境 对于我这个 Net程序员 那就肯定离不开安装 SQL Server 了 网上没有找到很详细的教程 所以决定自己再写一份 下面直接进入主题 下载SQL Se
  • 基于 Matlab 的 RLS 算法进行时间序列预测

    基于 Matlab 的 RLS 算法进行时间序列预测 时间序列分析在许多领域中都具有重要的应用价值 例如金融 经济 气象等 时间序列预测是其中的一个关键问题 其目的是根据过去一段时间的观测值来预测未来一段时间的值 在本文中 我们将介绍如何使
  • Vue中安装less-loader报错处理

    Vue中使用less 需要安装less loader 1 安装命令 npm install less loader 需要注意的是less loader版本需要和webpack版本对应 版本不对会报错 webpack 4 使用 less lo
  • 【ML on Kubernetes】第 10 章:构建、部署和监控模型

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 从主机备份ubuntu到虚拟机的坑

    系统用的是16 04 1 备份过程 直接采用这个方法 不过我是直接用的镜像 data放在U盘 没有做成启动U盘 参考链接1 问题就来了 直接挂载镜像使用的是CD ROM 可能出现权限问题无法修改 记住要提前把必要的文件保存在虚拟机的系统下
  • Python自动化测试专栏——选择元素基本方法之CSS选择器

    CSS选择器选择元素 1 根据 tag名选择元素 选择 所有的tag名为div的元素 wd find elements by css selector div 2 根据id属性选择元素 wd find element by css sele
  • tensorflow如何更新到最新的版本

    背景 前面在anaconda中使用tensorflow时 在深度学习目标检测的那方面出现了问题 提示 no op 当你在百度上百度这个错误的时候 很多的CSDN博主会告诉你是因为你的tensorflow版本过低 准备 那就是更新tensor
  • MySQL——习题:每个部门当前员工最高薪水

    有一个员工表dept emp简况如下 有一个薪水表salaries简况如下 获取所有部门中员工薪水最高的相关信息 给出dept no emp no以及其对应的salary 按照部门编号升序排列 以上例子输出如下 解法1 SELECT d1
  • 移植Qt4.8.4项目到QT5.2上时遇到的一些问题

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 问题1 Qt 5 2 使用原来的QT4 8 4项目时QWebView QWebFrame等类无法编译通过 出现原因 QWebView QWebFrame QWebPage
  • OJ: 蛇形矩阵 螺旋矩阵

    题目描述 题目说明 在一个N N的方阵中 填入1 2 N共N个数 并要求构成如下的格式 N lt 10 例 输入描述 多组数据 每行读入一个N 输出描述 对应输出N N的蛇形矩阵 每个数字占3格子 每个蛇形矩阵之间用空行分割 输入样例 3
  • 【Git】git pull总是要输入账号和密码

    git config global credential helper store 之后再次执行git push 或者git pull这时候只需要在输入一次用户名和密码下次就不需要了 这个命令则是在你的本地生成一个账号密码的记录 这样就不用
  • Python中执行MySQL语句, 遇到同时有单引号, 双引号处理方式 !r, repr()

    SQL语句 insert cmd INSERT INTO 0 SET 1 format db conn firmware info table join 0 1 r format k str v for k v in info dict i
  • linux读取按行读写文本文件

    include
  • 迪杰斯特拉算法浅析

    所谓的迪杰斯特拉算法 就是一个用来求一个图中某点到其它点的最短路径的算法 大致方法 遍历所有节点 找到离起点最近的一个点 那么这个点到起点的最小距离肯定是起点到这个点的这条边的权值 然后标记这个点被使用过了 以1中的那个点为中继 更新其它节
  • 进程和线程的区别

    简介 进程 进程是计算机中运行程序的实例 是操作系统进行资源分配和调度的基本单位 每个进程都有独立的内存空间和系统资源 不同进程之间相互独立 彼此不能直接访问对方的内存 进程之间的通信需要通过操作系统提供的特定机制 如管道 共享内存等 个人
  • nginx 之安全配置

    前言 看官网官网 一 控制并发连接数 1 在默认发布目录新建一个目录并保存一张图片 传送文件到server1 打开浏览器就能看到图片 2 测试 查看日至情况 cat usr local nginx logs access log http状
  • 时间计时android程序,Android实现时间倒计时功能

    本文实例为大家分享了Android实现时间倒计时功能展示的具体代码 供大家参考 具体内容如下 效果展示 MainActivity 主页面代码 public class MainActivity extends Activity privat
  • Nacos配置中心落地与实践

    一 背景 目前 我们公司各团队配置中心使用各异 电商使用的是 Spring Cloud Config 支付使用的是 Apollo APP 团队使用的是 Apollo Nacos 为了更好地应对公司业务的发展 统一基础设施技术栈必不可少 图片