手写分布式配置中心(一)

发布于:2024-10-24 编辑:匿名 来源:网络

1 什么是分布式配置中心,其实就是将一些配置信息从自己的系统中分离出来,并且这些信息可以被应用程序实时获取。这里我们以springboot为例。

我们都知道springboot启动时会加载资源目录下的application.properties或者application.yml。这时我们把springboot启动时需要加载的配置文件和项目放在一起,统一管理。

这就是分布式配置中心的核心思想。 1.1 分布式配置中心由哪些部分组成? 1.1.1.有一个可以操作配置的界面。

1.1.2.数据可以持久化(防止丢失,服务离线时配置仍然存在)。 1.1.3.有一个客户端和一个服务器。

,客户端主动拉取数据或者服务端主动推送数据。并刷新本机的配置。

(核心)1.1.4、管理界面、权限系统等一些操作日志。 2、市面上主流的配置中心2.1阿里巴巴的nacosNacos致力于帮助您发现、配置和管理微服务。

Nacos 提供了简单易用的功能集,帮助您快速实现动态服务发现、服务配置、服务元数据和流量管理。 Nacos 帮助您更敏捷、更轻松地构建、交付和管理微服务平台。

Nacos是构建以“服务”为中心的现代应用架构(如微服务范式、云原生范式)的服务基础设施。具体使用请参见官网2.2。

nacos的原理是通过长链接来监控服务配置是否发生变化。发送给客户端的架构示意图如下。

这是推送模式,但它是基于长链接image.png2.3。携程的ApolloApollo是携程框架部开发并开源的生产级配置中心产品。

它可以集中管理不同环境、不同集群的配置中的应用,配置修改后可以实时推送到应用端,并具有标准化的权限、流程治理等特性,适合微服务配置管理场景。具体使用方法请查看官网。

携程的架构示意图和Nacos是一样的。也是长链接轮询和服务器推送模式。

2.3 spirgcloud configspringCloudConfig,支持将配置服务放置在配置服务的内存中(即本地),也支持放置在远程Git/svn仓库中。当image.png服务启动时,config服务会从远程git拉取配置文件并存储到本地git文件库中。

当远程git不可用时,将从本地git文件库中拉取配置信息。具体使用方法请以官网为准。

2.4 百度disconf Disconf是百度开源的一款基于Zookeeper的分布式配置管理软件。目前,很多公司都在使用,包括滴滴、百度、网易、顺丰速运等公司。

通过简单的界面操作就可以非常方便的动态修改配置属性。使用Disconf后发现的一大好处是不需要应用大量配置,并且配置可以自动加载并实时生效。

基本原理图:当然,具体的肯定比这个复杂,这只是主要流程。 image.png3 如何实现自己的分布式配置中心 3.1 动态修改本地@Value注解配置 3.2 如何同时修改不同bean中的同一个值。

4、关于如何动态修改@Value注解的配置的具体思路,我们需要知道springboot是如何加载application.ym或application.properties文件的。我这里使用springboot2.1.1的代码作为演示。

首先打开image.png,找到spring.factors的配置文件image.png。我们看到上面三个是配置文件的加载器。

这也说明了为什么properties的优先级高于yaml。他按照从上到下的顺序排列。

但实际的配置文件仍然执行如下。我们点击查看实现类ConfigFileApplicationListene的代码语言: javascript copy @Overridepublic void postProcessEnvironment(ConfigurableEnvironmentenvironment, SpringApplication application) { //如何加载资源 addPropertySources(environment, application.getResourceLoader()) ;}protected void addPropertySources(ConfigurableEnvironment)环境,ResourceLoader资源加载器){RandomValuePropertySource.addToEnvironment(环境); // 将资源加载到环境变量中 new Loader(environment, resourceLoader).load(); }// 然后使用propertySource解析器进行解析 Loader(ConfigurableEnvironmentenvironment, ResourceLoaderresourceLoader) { this.environment =environment; } this.placeholdersResolver = new PropertySourcesPlaceholdersResolver( this.environment); this.resourceLoader = (resourceLoader!= null) ?资源加载器:新的默认资源加载器(); this.propertySourceLoaders = SpringFactoriesLoader.loadFactories( PropertySourceLoader.class, getClass().getClassLoader());} 那么我们就知道了,就是如果我们能够环境PostProcessor,我们就可以通过重写里面的方法来动态加载配置文件。

现在我们开始代码实现。 4.1 代码实现 这种情况下,我们可以实现EnvironmentPostProcessor类,通过接口动态加载配置文件。

那么下面是具体的代码实现代码语言:txt copy @AutowiredConfigurableEnvironmentconfigurableEnvironment; @AutowiredEnvironment环境; @Testpublic void test() { String name =environment.getProperty("name"); System.out.printf("动态加载前" +name); Map map = new HashMap<>(); map.put("名字","嘟嘟"); configurableEnvironment.getPropertySources().addLast( new OriginTrackedMapPropertySource("xxxx.xml", map) );字符串属性=环境.getProperty(“名称”); System.out.printf("动态加载后" +property);}4.1.2 单元测试最终结果为image.png。现在我们已经解决了第一个问题,第二个问题就是如何动态添加环境变量。

第二个问题是如何动态刷新@value注解。那么对于这个用途,我们需要ConfigurablePropertyResolver类来解析key,找到@value对应的bean后,通过反射刷新具体代码 4.2 代码实现代码语言:txt copy public static voidfreshBean(Object bean, ConfigurablePropertyResolver propertyResolver) { // 定义 EL 表达式解释器 SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); TemplateParserContext templateParserContext= new TemplateParserContext();字符串 keyResolver, valueResolver = null;对象解析器值; // 获取真实对象属性 Field[] declaredFields = bean.getClass().getDeclaredFields (); boolean cglib = Arrays.stream(declaredFields).anyMatch(x -> x.getName().contains("CGLIB")); // 如果是cglib代理,则找到其父类 if(cglib){ declaredFields = bean .getClass().getSuperclass().getDeclaredFields(); } // 遍历Bean实例的所有属性 for (Field field : declaredFields) { // 判断field是否包含@Value注解 if (field.isAnnotationPresent(Value.class)) { // 读取Value注解占位符 keyResolver = field.getAnnotation(Value.clas).value(); try { // 读取属性值 valueResolver = propertyResolver.resolveRequiredPlaceholders(keyResolver); // EL表达式解析 // 兼容形如:@Value("#{'${codest. Five.url}'.split(',')}") 含有EL表达式的情况 Expression expression = spelExpressionParser.parseExpression (valueResolver, templateParserContext); if(field.getType() == Boolean.class){ parserValue =Boolean.valueOf(expression.getValue().toString()); } else if(field.getType() == Integer.class){ parserValue =Integer.valueOf(expression.getValue().toString()); } else if(field.getType() == Long.class){ parserValue =Long.valueOf(expression.getValue().toString()); }else { parserValue = expression.getValue(field.getType()); }} catch (IllegalArgumentException e) { 继续; } // 判断配置项是否存在 if (Objects.nonNull(valueResolver)) { field.setAccessible(true);尝试 { field.set(bean, parserValue);继续; } catch ( IllegalAccessException e) { e.printStackTrace();我们正在编写一个单元测试 Test 4.2.1 单元测试 image.pngimage.png 代码语言:txt copy @AutowiredConfigurableEnvironmentconfigurableEnvironment; @AutowiredConfigurablePropertyResolver 可配置PropertyResolver; @AutowiredPerson 人; @Testpublic void test() { System.out.printf("动态加载前" +person.getName()); Map map = new HashMap<>(); map.put("名字","嘟嘟"); configurableEnvironment.getPropertySources().forEach( x->{ if (x instanceof OriginTrackedMapPropertySource ) { Map map1 = (Map) x.getSource(); map1.putAll(地图); } } );刷新Bean(人,configurablePropertyResolver); System.out.printf("动态加载后" + person.getName());} 最终结果:image.png 完美。

下一期我们将解决当多个bean具有相同@value值时如何同时刷新特定文档的问题。我们先挖金子。

请关注掘金队。

手写分布式配置中心(一)

站长声明

版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

标签:

相关文章

  • 自动驾驶初创公司Momenta获得4600万美元B轮投资,蔚来资本领投

    自动驾驶初创公司Momenta获得4600万美元B轮投资,蔚来资本领投

    据投资界7月25日消息,自动驾驶初创公司Momenta获得4600万美元B轮投资,由蔚来资本领投,戴姆LE集团(梅赛德斯-奔驰母公司)、顺为资本、创新工场、九合创投也参与投资。   此前,今年11月,Momenta公司获得蓝湖资本领投的A轮融资,创新工场、真格基金跟投。 年初获得顺为资

    06-18

  • 郑州需要各方支持,未来法拉第合并上市

    郑州需要各方支持,未来法拉第合并上市

    7月20日,郑州遭遇特大暴雨,道路淹水严重,雨水涌进地铁,成为了一个令人心惊胆战的夜晚。 无数郑州人的心。 在灾难面前,一个人特别渺小,但在一起就很伟大。 昨天晚间,腾讯公益基金会率先紧急公布第一批1亿元捐款,并在其平台设立“河南抗洪救助”版块,为全国网友开通捐

    06-17

  • 为什么视觉中国不敢加图

    为什么视觉中国不敢加图

    被告拍的照片侵权?如果对方是视觉中国,似乎也没什么奇怪的。 2016年,视觉中国发布首张全人类共享的黑洞照片,并因声称拥有国旗、国徽图像版权而受到批评。 近日,在广撒维权的同时,遭遇了该图片的“亲生父亲”。 李鬼去了李逵,但子弹还要飞一段时间。 我们先按照时间线回

    06-21

  • 2023中国游戏产业年会暨ChinaJoy展会二十周年庆典在广州隆重举行

    2023中国游戏产业年会暨ChinaJoy展会二十周年庆典在广州隆重举行

    国家新闻出版总署指导,广东省新闻出版局、广州市委宣传部支持中共中央、中国音像数字出版协会、广州开发区主办,广州市黄埔区管委会、人民政府主办,中国音乐与数字协会游戏工作委员会、宣传部承办中共广州市黄埔区委、黄埔文化(广州)发展集团有限公司、黄埔文商旅游(广州

    06-18

  • 优衣库首次在门店出售咖啡,每杯12元

    优衣库首次在门店出售咖啡,每杯12元

    逛累了喝一杯咖啡,陪孩子和哆啦A梦比赛,走前带上一束鲜花。 所有这些体验都可以在优衣库银座店一站式实现。 9月17日,优衣库位于日本东京银座的全球旗舰店装修后重新开业。 这家已有10年历史的12层店位于豪华购物中心GINZA SIX的正对面。 ▲ 图片来自:日经中文网 这家店改

    06-21

  • 疫情过后,医疗健康该如何投资?

    疫情过后,医疗健康该如何投资?

    疫情期间如何投资VC/PE?近日,前海深港基金小镇与投资界在深圳前海深港基金小镇路演中心联合举办了主题为“疫情下的投资天堂——医疗健康”的论坛。 前海深港基金小镇董事长蔡杰、深圳创投健康产业基金投资部总经理周毅、高特嘉研究部高管合伙人张鹏、华大共赢投资合伙人纪昌

    06-18

  • 有消息称开心网赴美上市或遇阻,被指错失最佳时机

    有消息称开心网赴美上市或遇阻,被指错失最佳时机

    7月15日,投资界消息称,前国内SNS明星公司开心网遭遇其赴美上市遭遇重重阻碍,错失最佳时机。 首次公开募股的机会。   上述消息人士表示,开心网由于自身流量下降、资本市场环境不佳以及中概股诚信问题,在申请IPO过程中遇到了很大困难,SEC (美国证券交易委员会)开心网

    06-18

  • 纪念查理·芒格|蓝驰分享

    纪念查理·芒格|蓝驰分享

    纪念查理芒格|蓝驰分享笔记 蓝驰创投 蓝驰创投 微信ID蓝池创投关于特色 蓝驰创投中国成立于2016年,专注于早期风险投资,管理资金超亿元,累计投资超亿元。 创业企业,是理想汽车、水滴公司、青云、瓜子二手车、怪兽充电、云图、宏景智家、云升智能、百图生物等优秀企业的早

    06-18

  • 首次发布 -瑞讯生物完成数千万元C1轮融资,产品已进入多家三级医院

    首次发布 -瑞讯生物完成数千万元C1轮融资,产品已进入多家三级医院

    投资界(ID:pedaily)11月17日消息,近日,基于微流控自研技术平台,深耕微流控诊断与生命科学公司领导者瑞讯生物完成数千万元C1轮融资。 本轮融资由千岛基金领投,皓月资本担任本轮融资独家保荐人。 瑞讯生物成立于2007年,位于苏州工业园区。 其在美国硅谷生命科学产品线拥

    06-17

  • 植物蛋白饮料品牌“燕麦”完成数千万元A轮融资,由五源资本领投

    植物蛋白饮料品牌“燕麦”完成数千万元A轮融资,由五源资本领投

    植物蛋白饮料品牌“燕麦”完成数千万元A轮融资,领投婺源资本。 股东华创资本和imo Ventures也参与了投资,其中棕榈资本为财务顾问。 本轮融资将主要用于线下渠道拓展和品牌建设。

    06-17

  • 深圳有一款游戏出现在98%的朋友圈里,你确定不想约会吗?

    深圳有一款游戏出现在98%的朋友圈里,你确定不想约会吗?

    生活中的种种诱惑,存在于每一句话中。 比如:有的人做的家常菜生动鲜美,有的人28天练出人鱼线,有的人一年加薪好几次,年纪轻轻年薪50万+。 有些人可以朝九晚五工作并环游世界。 过着耀眼而美好的生活……当你在生活中彷徨,陷入各种诱惑时,突然有一股力量从千里之外传来。

    06-18

  • 人力资源企业服务商“礼才网”完成3亿元C1轮融资

    人力资源企业服务商“礼才网”完成3亿元C1轮融资

    8月6日消息,“礼才网”完成3亿元C1轮融资。 中投信联、广信资本、中南泊富基金、诚煜资本、德信基金等投资,创始人和CEO陈谏也参与投资。 融资金额将用于PaaS+小生态开发以及基于AI的HR专业管理产品的研发。 “理才网”成立于2007年,是一家以人力资源服务为核心的企业服务

    06-18