应用配置管理,基础原理分析

工程可以有点小乱,但配置不能含糊;

一、配置架构

在微服务的代码工程中,配置管理是一项复杂的事情,即需要做好各个环境的配置隔离措施,还需要确保生产环境的配置安全;如果划分的微服务足够的多,还要考虑配置更新时的效率;

应用配置管理,基础原理分析

常规情况下,在配置管理的体系中,分为四个主要的环境:开发、测试、灰度、生产;通常来说除了运维团队之外,其他人员没有查看灰度和生产配置的权限,以此来保证配置的安全性;配置中心的服务也会搭建两套:研发与生产各自独立部署。

二、配置方式

在项目中涉及到的配置非常多,类型也很多,但是从大的结构上可以分为:工程级、应用级、组件级三大块;实际上这里只是单纯的从代码工程来看配置,如果把持续集成、自动化相关模块也考虑进来的话,配置的管理会更加复杂;

应用配置管理,基础原理分析

站在开发的角度来看,主要还是对应用级的配置进行管理,而在微服务的架构下,多个不同的服务既有大量相同的配置,又存在各种差异化的自定义参数,所以在维护上有一定的复杂性;

应用配置管理,基础原理分析

在单服务的工程中,应用中只会存在一个 bootstrap.yml配置文件,配置内容基本就是服务名称,和配置中心地址等常规内容,其他复杂的配置都被封闭维护,避免核心内容泄露引发安全问题;

应用配置管理,基础原理分析

配置主体通常会被拆分成如下几个层次:环境控制,用来识别灰度和生产;应用基础,管理和加载各个服务的通用配置;服务差异则配置在各自独立的文件内;并且对多个配置进行分类分层管理;以此保证配置的安全和降低维护难度。

三、Nacos配置

首先还是从 bootstrap.yml文件作为切入点,以当下常见的Nacos组件为例,围绕基础原理作为思路,来分析服务工程是如何加载Nacos配置中心的参数;

spring:
  profiles:
    active: dev,facade
  cloud:
    nacos:
      config:
        prefix: application
        server-addr: 127.0.0.1:8848
        file-extension: yml

应用配置管理,基础原理分析

组件配置:配置逻辑中,单个服务端提供自身配置参数的信息,从上篇服务管理的源码中发现,这是一种很常用的手段;需要基于这些信息去Nacos服务中加载配置;

@ConfigurationProperties("spring.cloud.nacos.config")
public class NacosConfigProperties {
    public Properties assembleConfigServiceProperties() {
        Properties properties = new Properties();
        properties.put("serverAddr", Objects.toString(this.serverAddr, ""));
        properties.put("namespace", Objects.toString(this.namespace, ""));
        return properties ;
    }
}

加载逻辑:服务启动时,先基于相应参数读取Nacos中配置的,然后解析数据并被Spring框架进行加载,加载的过程通过MapPropertySource类进行Key和Value的读取;

public class NacosPropertySourceBuilder {
    private List> loadNacosData(String dataId, String group, String fileExtension) {
        // 查询配置
        String data = this.configService.getConfig(dataId, group, this.timeout);
        // 解析配置
        return NacosDataParserHandler.getInstance().parseNacosData(dataId, data, fileExtension);
    }
}

请求服务:服务端与Nacos中心通过Http请求的方式进行交互,通过Get请求携带参数,调用Nacos中心服务,从而获取相应配置;

public class ClientWorker implements Closeable {
    public String[] getServerConfig(String dataId, String group, String tenant, long readTimeout) {
        // 核心参数
        Map params = new HashMap(3);
        params.put("dataId", dataId);
        params.put("group", group);
        params.put("tenant", tenant);
        // 执行请求
        HttpRestResult result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
    }
}

四、Spring加载

从源码的结构图来看,配置文件的加载逻辑也是采用事件模型实现的,这在前面任务管理中有详细的描述;配置的核心作用就是在程序启动时进行加载引导,这里关键要理解 EnvironmentPostProcessor的接口设计;

应用配置管理,基础原理分析
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
    // 基础配置
    private static final String DEFAULT_NAMES = "application";
    public static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active";
    public static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include";
    static {
        Set filteredProperties = new HashSet<>();
        filteredProperties.add("spring.profiles.active");
        filteredProperties.add("spring.profiles.include");
        LOAD_FILTERED_PROPERTY = Collections.unmodifiableSet(filteredProperties);
    }
    // 加载逻辑
    void load() {
    FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY,
            (defaultProperties) -> {
            });
    }
}

EnvironmentPostProcessor接口:加载应用的自定义环境;

@FunctionalInterface
public interface EnvironmentPostProcessor {
    void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);
}

SpringApplication:用于启动和引导应用程序,提供创建程序上下文实例,初始化监听器,容器刷新等核心逻辑,可以围绕 run()方法进行调试分析;

ConfigurableEnvironment:环境配置的核心接口,涉及到当前配置文件识别,即 profiles.active;以及配置文件的解析能力,即 PropertyResolver;在 Loader内部类中提供了构造方法和加载逻辑的实现。

五、参考源码

&#x5E94;&#x7528;&#x4ED3;&#x5E93;&#xFF1A;
https://gitee.com/cicadasmile/butte-flyer-parent

&#x7EC4;&#x4EF6;&#x5C01;&#x88C5;&#xFF1A;
https://gitee.com/cicadasmile/butte-frame-parent

Original: https://www.cnblogs.com/cicada-smile/p/16395449.html
Author: 知了一笑
Title: 应用配置管理,基础原理分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/610891/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Twikoo私有化部署教程–迁移腾讯云

    备份数据 私有化部署 创建容器 导入数据 重新配置twikoo面板设置 引入前端CDN Nginx https反代http 作者:小牛呼噜噜 | https://xiaoniuhu…

    Linux 2023年6月6日
    0147
  • Docker-dockerfile

    Docker-通过Dockerfile创建镜像 1.Dockerfile简介 简而言之,Dockerfile 是一个描述如何创建 Docker 镜像所需步骤的文本文件。 一个Doc…

    Linux 2023年6月13日
    098
  • 我叫Mongo,干了「查询终结篇」,值得您拥有

    这是mongo第三篇”查终结篇”,后续会连续更新5篇 mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟…

    Linux 2023年6月14日
    0134
  • 2020年12月-第02阶段-前端基础-品优购项目规范

    代码规范 1. 概述 欢迎使用品优购代码规范, 这个是我借鉴京东前端代码规范,组织的品优购内部规范。旨在增强团队开发协作、提高代码质量和打造开发基石的编码规范, 以下规范是团队基本…

    Linux 2023年6月8日
    0114
  • centos7 删除grub2 开头的所有文件后故障修复

    环境:centos7 mini故障原因:删除根目录,/boot以及/boot/efi下递归查找到的所有grub2 开头的文件现象:无法正常开机,开机显示下图 解法(该解法过程中照片…

    Linux 2023年6月6日
    0146
  • Xshell中文乱码问题

    先查看当前使用的语言: echo $LANG 查看系统的语言安装包: locale 如果没有中文安装包(包含zh_CN字样),需要网络或者自己上传安装包,安装 有了中文语言安装包后…

    Linux 2023年5月28日
    0101
  • 位运算(一)

    位运算的一般应用 功能 例子 运算 去掉最后一位 1110101->111010 x>>1 在最后加0 1110101->11101010 x< 通过…

    Linux 2023年6月8日
    0145
  • 增加Apache响应时间

    在apache的配置文件 httpd.conf 最下面加上下面代码,增加响应时间 FcgidProcessLifeTime 8200 FcgidIOTimeout 8200 Fcg…

    Linux 2023年6月7日
    0103
  • mysql order by语句流程是怎么样的

    order by流程是怎么样的 注意点: select id, name,age,city from t1 where city=’&#x676D;&#x5DDE;…

    Linux 2023年6月8日
    0115
  • 算法小技巧 — 链表

    一、快慢指针 1、核心思想 【核心思想:】 采用双指针完成,一个指针永远比另一个指针稍快一点。 【常见案例:】 找到单链表的中间节点    环形链表 【单链表结构:】 class …

    Linux 2023年6月14日
    080
  • 软件测试基础理论(2)

    一, 为什么要进行软件测试 &#x4E3A;&#x4E86;&#x901A;&#x8FC7;&#x8F6F;&#x4EF6;&amp…

    Linux 2023年6月7日
    0119
  • Linux运行Jar包方式

    1 运行Jar包 第一种方式 java -jar xxx.jar 最基本的方式,程序运行的信息会一直输出在控制台,ctrl+c中断或者关闭窗口时,程序中断执行。 第二种方式 jav…

    Linux 2023年6月7日
    0110
  • JAVA设计模式-适配器模式

    JAVA设计模式-适配器模式 介绍 适配器模式是一种结构型模式,它主要解决接口之间的兼容问题。当我们需要使用某个类的接口时,但是这个类的接口目前并不符合我们使用需求,不能直接使用,…

    Linux 2023年6月6日
    0114
  • 五分钟搭建博客系统 OK?

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 概要: 通过 Docker Compose 在使用 Docker容器构建的隔离环境中轻松运行 WordPress。…

    Linux 2023年6月14日
    0146
  • DHCP服务

    一、dhcp介绍 dhcp 应用层协议 动态主机配置协议 作用: 为主机动态分配tcp/ip参数(ip地址、掩码、网关、DNS服务器地址) Linux实现dhcp服务 软件: dh…

    Linux 2023年6月7日
    089
  • RAID磁盘阵列技术

    RAID磁盘阵列技术 1、RAID概述 RAID(Redundant Array of Independent Disk),从字面意思讲的是基于独立磁盘的具有冗余的磁盘阵列,其核心…

    Linux 2023年6月7日
    0104
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球