从spring boot 启动过程看apollo的初始化过程( 二)
之前一篇文章《从apollo的初始化看spring boot 1.5.3启动过程( 一)》 说到而apollo的初始化逻辑便放在这里面,本文就继续从此展开
Spring从3.1版本开始增加了ConfigurableEnvironment
和PropertySource
:
-
ConfigurableEnvironment
Spring的ApplicationContext
会包含一个Environment
(实现ConfigurableEnvironment
接口) -
ConfigurableEnvironment
自身包含了很多个PropertySource
-
PropertySource
属性源, 可以理解为很多个Key - Value
的属性配置
而ConfigurableEnvironment
正是被传入postProcessEnvironment
方法中去执行自己想要初始化的属性源。
在运行时的结构形如:
需要注意的是,PropertySource
之间是有优先级顺序的,如果有一个Key
在多个property source
中都存在,那么在前面的property source
优先。
所以对上图的例子:
- env.getProperty(“key1”) -> value1
- env.getProperty(“key2”) -> value2
- env.getProperty(“key3”) -> value4
所以,在应用启动阶段,Apollo从远端获取配置,然后组装成PropertySource
并插入到第一个即可,如下图所示:
在配置中心中,一个重要的功能就是配置发布后实时推送到客户端。下面我们简要看一下这块是怎么设计实现的。
上图简要描述了配置发布的大致过程:
1、用户在Portal操作配置发布 2、Portal调用Admin Service的接口操作发布 3、Admin Service发布配置后,发送ReleaseMessage(此处的消息中间件为数据库)给各个Config Service
4、Config Service
收到ReleaseMessage
后,通知对应的客户端
而我们的应用程序是从apollo 的客户端client中去获取通知
上面说的从远端获取配置,那么如何从远端获取呢?
我们知道client
是从SLB
中发现metaServer
,进而读取Config Service
的 配置信息,
即和域名系统配合,协助Client
访问MetaServer
获取ConfigService
地址列表。
在 com/ctrip/framework/apollo/internals/ConfigServiceLocator.java
中,类初始化后,
#1、执行initialize这个方法
2、获取MetaService地址
3、获取环境信息
比如我的是windows环境,然后配置的本地的DEV开发环境
4、获取域名信息
这个domain是一个可以从一个自定义的apollo-env.properties文件获取并put相关配置后的Static Map
这里获取到的只是MetaService
的地址,即通过包装服务后的eureka
的地址,还要通过此地址,来发现configService
的无状态集群式部署的机器ip:port信息。
Meta Server从Eureka获取metaService,Config Service和Admin Service的服务信息,相当于是一个Eureka Client。增设一个Meta Server的角色主要是为了封装服务发现的细节,对Portal和Client而言,永远通过一个Http接口获取Admin Service和Config Service的服务信息,而不需要关心背后实际的服务注册和发现组件。
Meta Server只是一个逻辑角色,在部署时和Config Service是在一个JVM进程中的,所以IP、端口和Config Service一致。由于和Config Service部署在一个JVM中,所以相应的metaService也是都是多实例、无状态部署,保证了服务的高可用性。
如何发现呢?
通过euerka
发现,目前已经将
这两个服务注册成功。
5、获取ConfigService的配置信息
此时,就需要MetaService
提供的接口,来获取ConfigService
的地址。
可通过http api 接口访问获取只要在注册中心地址后拼接上我们的应用appid以及主机IP(其实可以不用拼接appid和主机ip,直接获取configservice的地址)
通过界面访问也是一样的结果
所以,这个DTO也是携程内部定义的
所有的配置信息,则从上面的那个instanceId 的value所指向的地址请求获取
然后通过portal即可访问到admin-service
。
简而言之,就是通过两条线路来访问数据,保证了服务上线后,我们可通过portal热更新数据,来改变应用读到的配置信息。
参考
https://github.com/ctripcorp/apollo/wiki/Apollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E8%AE%BE%E8%AE%A1#133-meta-server https://mp.weixin.qq.com/s/-hUaQPzfsl9Lm3IqQW3VDQ
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- CTO写的代码,真是绝了!
- 用 BERT 精简版 DistilBERT+TF.js,提升问答系统 2 倍性能
- docker浅入深出
- 一篇文章快速搞懂Qt文件读写操作
- C++核心准则T.20:避免定义没有明确语义的“概念”
- 机器学习之独热编码(One-Hot)详解(代码解释)
- TypeScript 实战算法系列(四):实现集合和各种集合运算
- 不知道怎么封装代码?看看这几种设计模式吧!
- 百分浏览器快捷键
- 深度神经网络权值初始化的几种方式及为什么不能初始化为零(1)
- Python_doc.1
- (24)Bash预定义变量
- 数组:每次遇到二分法,都是一看就会,一写就废
- OSPF 路由协议配置
- 项目实战 | 细节决定成败的渗透测试