【apollo在springboot中运行原理】

系列文章目录

Springboot源码分析之apollo配置


文章目录

  • 系列文章目录
  • 前言
  • 一、apollo是如何完成初始化的,拉取配置的呢
    • 1. apollo的初始化阶段
    • 2.初始化RemoteConfigRepository
    • 3.同步远程配置
    • 4.发布`ConfigFileChangeEvent`事件
  • 总结


前言

配置中心我相信有一年开发经验的程序员都听过吧,有三年开发经验的程序100%都使用过配置中心配置吧。apollo做为常用的配置中心,你知道它的原理吗?你知道它是怎么集成到springboot的吗?
本篇文章带你了解其原理,让你也能够自定义组件。


一、apollo是如何完成初始化的,拉取配置的呢

1. apollo的初始化阶段

Springboot环境准备阶段,发布ApplicationEnvironmentPreparedEvent 事件,EnvironmentPostProcessorApplicationListener 监听到事件之后 执行 postProcessEnvironment方法。apollo 中 的初始化类 ApolloApplicationContextInitializer 就实现EnvironmentPostProcessor接口。
ApolloApplicationContextInitializer

  public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {// should always initialize system properties like app.id in the first placeinitializeSystemProperty(configurableEnvironment);Boolean eagerLoadEnabled = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED, Boolean.class, false);//EnvironmentPostProcessor should not be triggered if you don't want Apollo Loading before Logging System Initializationif (!eagerLoadEnabled) {return;}Boolean bootstrapEnabled = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, Boolean.class, false);if (bootstrapEnabled) {DeferredLogger.enable();//重点实现逻辑的方法initialize(configurableEnvironment);}}

2.初始化RemoteConfigRepository

经过initialize()方法层层调用最后进入到RemoteConfigRepository init

  public RemoteConfigRepository(String namespace) {m_namespace = namespace;m_configCache = new AtomicReference<>();m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);m_httpClient = ApolloInjector.getInstance(HttpClient.class);m_serviceLocator = ApolloInjector.getInstance(ConfigServiceLocator.class);remoteConfigLongPollService = ApolloInjector.getInstance(RemoteConfigLongPollService.class);m_longPollServiceDto = new AtomicReference<>();m_remoteMessages = new AtomicReference<>();m_loadConfigRateLimiter = RateLimiter.create(m_configUtil.getLoadConfigQPS());m_configNeedForceRefresh = new AtomicBoolean(true);m_loadConfigFailSchedulePolicy = new ExponentialSchedulePolicy(m_configUtil.getOnErrorRetryInterval(),m_configUtil.getOnErrorRetryInterval() * 8);//下面三个方法就是拉去配置的核心代码了  //同步远程配置 this.trySync();//固定频率刷新、内部实现也是调用trySync()this.schedulePeriodicRefresh();//轮询访问远程配置中心,每次访问直到超时或者apollo 配置发生变化this.scheduleLongPollingRefresh();}

3.同步远程配置

AbstractConfigRepository.trySync()同步远程配置方法,方法内部主要实现逻辑在sync()

protected synchronized void sync() {Transaction transaction = Tracer.newTransaction("Apollo.ConfigService", "syncRemoteConfig");try {//m_configCache ApolloConfig previous = m_configCache.get();//加载 远程 apollo configApolloConfig current = loadApolloConfig();//reference equals means HTTP 304if (previous != current) {logger.debug("Remote Config refreshed!");m_configCache.set(current);//getConfig 方法 将apollo配置放进 properties中this.fireRepositoryChange(m_namespace, this.getConfig());}if (current != null) {Tracer.logEvent(String.format("Apollo.Client.Configs.%s", current.getNamespaceName()),current.getReleaseKey());}transaction.setStatus(Transaction.SUCCESS);} catch (Throwable ex) {transaction.setStatus(ex);throw ex;} finally {transaction.complete();}}

private volatile AtomicReference<ApolloConfig> m_configCache; 使用了volatile 修饰,原子引用类型进行封装引用,这就是看源码的意义吧

4.发布ConfigFileChangeEvent事件

sync() 方法中的 调用fireRepositoryChange(),最后会调用到AbstractConfigFile.fireConfigChange()方法

  private void fireConfigChange(final ConfigFileChangeEvent changeEvent) {for (final ConfigFileChangeListener listener : m_listeners) {m_executorService.submit(new Runnable() {@Overridepublic void run() {String listenerName = listener.getClass().getName();Transaction transaction = Tracer.newTransaction("Apollo.ConfigFileChangeListener", listenerName);try {//listner 是一个PropertySourcesProcessor 中的一个lambda 类,//ConfigChangeListener configChangeEventPublisher = changeEvent ->//applicationEventPublisher.publishEvent(new ApolloConfigChangeEvent(changeEvent));listener.onChange(changeEvent);transaction.setStatus(Transaction.SUCCESS);} catch (Throwable ex) {transaction.setStatus(ex);Tracer.logError(ex);logger.error("Failed to invoke config file change listener {}", listenerName, ex);} finally {transaction.complete();}}});}}

因此我们可以监听ApolloConfigChangeEvent事件来监听apollo配置是否发生产变化
eg:

public class ListenerApollo implements ConfigChangeListener, ApplicationListener<ApolloConfigChangeEvent> {@Overridepublic void onChange(ConfigChangeEvent configChangeEvent) {//核心线程配置发生变化、重新setConfigChange coreSize = configChangeEvent.getChange("threadPool.corePoolSize");if( coreSize!= null){ThreadPoolExecutor executor = SpringUtil.getBean(ThreadPoolExecutor.class);executor.setCorePoolSize(Integer.valueOf(coreSize.getNewValue()));}}@Overridepublic void onApplicationEvent(ApolloConfigChangeEvent event) {this.onChange(event.getConfigChangeEvent());}
}

总结

分析apollo在Springboot启动的哪个环节被集成初始化的,以及跟了同步远程配置的逻辑,初始化时同步一次,定时同步,长轮询监听配置是否发生变化,发生变化又通知程序进行同步。并且同步后也会发布一个ApolloConfigChangeEvent事件,放开发者去监听配置变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/643888.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【STM32】STM32F4中USB的CDC虚拟串口(VCP)使用方法

文章目录 一、前言二、STM32CubeMX生成代码2.1 选择芯片2.2 配置相关模式2.3 设置时钟频率2.4 生成代码2.5 编译并下载代码2.6 结果2.7 问题 三、回环测试3.1 打开工程3.2 添加回环代码3.3 编译烧录并测试 四、出现问题和解决方法4.1 烧录总是要自己插拔USB4.2 自己生成的工程没…

【win】Windows下MSI Afterburner如何让其不在某个软件中显示帧数

本文首发于 慕雪的寒舍 Windows下MSI Afterburner如何让其不在某个软件中显示帧数 1.问题说明 总所周知&#xff0c;MSI Afterburner这个软件可以在游戏里面展示你当前电脑的各项生命体征&#xff0c;包括GPU/CPU功耗频率温度&#xff0c;内存占用&#xff0c;当前帧数等等数据…

java重写与重载的区别详细讲解通俗易懂

重写&#xff08;Override&#xff09;和重载&#xff08;Overload&#xff09;是Java中的两个重要概念&#xff0c;它们都涉及到方法的使用和定义。下面我会通俗易懂地解释它们的区别。 重写&#xff08;Override&#xff09;指的是在子类中重新定义父类中已经存在的方法&…

OpenKruiseGame × KubeSphere 联合发布游戏服运维控制台,推动云原生游戏落地

作者&#xff1a;云原生游戏社区 近日&#xff0c;云原生游戏开源社区旗下 OpenKruiseGame&#xff08;以下简称&#xff1a;OKG&#xff09;基于 KubeSphere 4.0 LuBan 架构开发的游戏服运维控制台 OKG Dashboard 正式发布&#xff01;现已上架 KubeSphere Marketplace 云原生…

32、WEB攻防——通用漏洞文件上传二次渲染.htaccess变异免杀

文章目录 一、点过滤二、文件删除三、二次渲染四、.htaccess五、过滤php关键函数 一、点过滤 不能写带文件后缀的文件名&#xff1b;IP转数字 二、文件删除 文件依据规则进行删除&#xff0c;删除有两种删除的类型&#xff1a; 什么文件都删除&#xff0c;条件竞争进行绕过…

宠物热潮席卷欧美:探秘宠物经济的蓬勃发展与增长动力

近年来&#xff0c;宠物经济在欧美地区蓬勃发展&#xff0c;成为经济体系中一股不可忽视的力量。从宠物食品到医疗护理&#xff0c;从宠物用品到服务业&#xff0c;整个产业链日益完善&#xff0c;呈现出多元化、高度专业化的趋势&#xff0c;不仅满足了宠物主人的需求&#xf…

Node.JS CreateWriteStream(大容量写入文件流优化)

Why I Need Node.JS Stream 如果你的程序收到以下错误&#xff0c;或者需要大容量写入很多内容(几十几百MB甚至GB级别)&#xff0c;则必须使用Stream文件流甚至更高级的技术。 Error: EMFILE, too many open files 业务场景&#xff0c;我们有一个IntradayMissingRecord的补…

LeetCode2865. Beautiful Towers I

文章目录 一、题目二、题解 一、题目 You are given a 0-indexed array maxHeights of n integers. You are tasked with building n towers in the coordinate line. The ith tower is built at coordinate i and has a height of heights[i]. A configuration of towers i…

TDengine 十大行业案例汇总,总有一款适合你!

伴随着产品的六载创新与发展&#xff0c;TDengine 的全球用户实例以日增 500 例在持续扩大。截至 2024 年初&#xff0c;TDengine 全球运行的实例数已经超过了 46 万&#xff0c;在物联网、车联网、工业互联网等多个领域都有了广泛的应用&#xff0c;越来越多的企业和组织选择使…

Java数据结构与算法:图算法之深度优先搜索(DFS)

Java数据结构与算法&#xff1a;图算法之深度优先搜索&#xff08;DFS&#xff09; 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;一个热爱编程的程序猿。今天&#xff0c;让我们一起探索图算法中的深度优先搜索&#xff08;DFS&…

《WebKit 技术内幕》学习之十二(1):安全机制

第12章 安全机制 安全机制对于浏览器和渲染引擎来说至关重要。一个不考虑安全机制的HTML5规范体系肯定不会受到广泛地使用&#xff0c;同时一个不安全的浏览器也不会得到广大用户的青睐。本章介绍的安全机制分成两个不同的部分&#xff0c;第一个部分是网页的安全&#xff0c;…

详解Mockito

详解Mockito 1. Mockito简介 在我们的编程世界中&#xff0c;测试是一个非常重要的环节&#xff0c;它能帮助我们确保代码的质量和稳定性。而在众多的测试方法中&#xff0c;Mock测试是一种非常有效的手段。 1.1 什么是 Mock 测试 Mock测试&#xff0c;顾名思义&#xff0c;…

gtest 单元测试

文章目录 前言一、Google Test介绍1.1 gtest源码下载编译1.2 gtest运行参数介绍 二、Google Mock参考资料 前言 Google Test&#xff08;简称gtest&#xff09;是一个开源的C单元测试框架。和常见的测试工具一样&#xff0c;gtest提供了单体测试常见的工具和组件。比如判断各种…

邦芒支招:10种小妙招让你准时下班

工作的人都希望能准时下班&#xff0c;都不希望加班&#xff0c;那么怎么做才能准时下班呢来看看下面这10种方法吧 1、提前整理文件 错误示范&#xff1a;一下班就冲出办公室&#xff0c;什么都不管。第二天怎么都找不到记着重要电话号码的便利贴了。 正确示范&#xff1a;离…

Linux CentOs7 安装Mysql(5.7和8.0版本)密码修改 超详细教程

CSDN 成就一亿技术人&#xff01; 今天出一期Centos下安装Mysql&#xff08;详细教程&#xff09;包括数据库密码跳过修改 CSDN 成就一亿技术人&#xff01; 目录 1.获取安装包 2.安装程序 安装下载的rpm包 查看安装包 修改5.7版本&#xff08;重要&#xff09; 安装M…

产品面试题2

39.产品经理在与 开发团队合作时&#xff0c;以下哪个角色负责将产品需求转化为可执行的任务&#xff1f; a) 技术经理 b) 交互设计师 c) 项目经理 d) 开发工程师 答案&#xff1a;c 40.以下哪个方法适用于评估产品的用户满意度和体验&#xff1f; a) 用户访谈 b) 用户调研问卷…

Win10设置有线网络和WiFi网络优先级-240124成功

Win10怎么设置有线网络和WiFi网络优先级? 修改“接口跃点数”方法成功。 使用ip.sb进行检验ip是否设置成功。

远程git开发

两种本地与远程仓库同步 """ 1&#xff09;你作为项目仓库初始化人员&#xff1a;线上要创建空仓库 > 本地初始化好仓库 > 建立remote链接(remote add) > 提交本地仓库到远程(push)2&#xff09;你作为项目后期开发人员&#xff1a;远程项目仓库已经创…

4.php开发-个人博客项目登录验证cookiesession验证码安全​

目录 知识点 本节大纲思路 ——这里以我自己的为例—— cookie验证——————> login1.php-登录后台界面 login_check.php-检查&#xff0c;作为包含文件 add_news.php-后台界面 php编码 如何创建 Cookie&#xff1f;--setcookie() 语法 实例 1 php header跳转…

(学习日记)2024.01.23:结构体、位操作和枚举类型

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…