Netflix Archaius 分布式配置管理依赖构件
来源:互联网 发布:java培优班 教哪些内容 编辑:程序博客网 时间:2024/05/18 02:41
Archaius 配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
概述
archaius是Netflix公司开源项目之一,基于java的配置管理类库,主要用于多配置存储的动态获取。主要功能是对apache common configuration类库的扩展。在云平台开发中可以将其用作分布式配置管理依赖构件。同时,它有如下一些特性:
- 动态类型化属性
- 高效和线程安全的配置操作
- 配置改变时的回调机制
- 轮询框架
- JMX,通过Jconsole检查和调用操作属性
- 组合配置
适用场景
对于传统的单体应用,properties等配置文件可以解决配置问题,同时也可以通过maven profile配置来区别各个环境,但在一个几百上千节点的的微服务生态中,微服务采用多种语言开发,配置文件格式多样,如何把每个微服务的配置文件都进行更新,并且很多时候还需要重启服务,是一件无法忍受的事情。所以,对于微服务架构而言,一个通用的配置中心是必不可少的。
新接口逻辑上线,老接口面临迁移,开发测试完成后,马上要上线。但是接口调用发的研发同学对新接口的稳定性、性能存在一定的质疑,为了避免风险,要求可以上线后紧急切换回老接口。这时候我们就需要一个手动开关。所以对于类似需求,一个通用的配置中心是必不可少的。
Archaius提供的DynamicIntProperty类可以在配置发生变化时动态地获取配置,并且不需要重启应用,而底层的配置存储,建议使用zookeeper进行存储,Archaius作为客户端的类库使用。
代码案例
引入依赖
<dependency> <groupId>com.netflix.archaius</groupId> <artifactId>archaius-core</artifactId></dependency>
自定义Configuration
PropertiesConfiguration
public class PropertiesConfiguration extends DynamicConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesConfiguration.class); private static final int INITIAL_DELAY_MILLIS = 0; private static final int DELAY_MILLIS = 60 * 1000; private static final boolean IGNORE_DELETES_FROM_SOURCE = true; public PropertiesConfiguration(String confDir) { this(new String[]{confDir}); } public PropertiesConfiguration(final String...confDirs) { String[] propertiesPaths = Lists.newArrayList(Iterables.concat(Iterables.transform(Arrays.asList(confDirs), new Function<String, List<String>>() { @Nullable @Override public List<String> apply(String confDir) { Assert.isTrue(new File(confDir).isDirectory(), StringUtil.format("路径[{}]无法查找[.properties]文件", confDirs)); String[] propertiesPaths = getPaths(confDir); if (ArrayUtils.isNotEmpty(propertiesPaths)) { return Lists.newArrayList(propertiesPaths); } else { return Lists.newArrayList(); } } }))).toArray(new String[0]); if (ArrayUtils.isNotEmpty(propertiesPaths)) { super.startPolling(new URLConfigurationSource(propertiesPaths), new FixedDelayPollingScheduler(INITIAL_DELAY_MILLIS, DELAY_MILLIS, IGNORE_DELETES_FROM_SOURCE)); } ConfigurationLog.successInit(PropertiesConfiguration.class, this.getProperties()); } private static String[] getPaths(String confDir) { try { URL configHome = new File(confDir).toURI().toURL(); List<String> urls = new ArrayList<String>(); for (String filename : FileUtil.scan(confDir, ".properties$")) { String url = configHome.toString() + filename; urls.add(url); } return urls.toArray(new String[urls.size()]); } catch (MalformedURLException e) { throw Throwables.propagate(e); } }}
SystemConfiguration
public class SystemConfiguration extends ConcurrentMapConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(SystemConfiguration.class); public SystemConfiguration() { super(); this.loadProperties(System.getProperties()); ConfigurationLog.successInit(SystemConfiguration.class, this.getProperties()); }}
同理,可以使用zookeeper client 封装一个基于zookeeper的 ConcurrentMapConfiguration
初始化
private static final ConcurrentCompositeConfiguration compositeConfig = new ConcurrentCompositeConfiguration();public synchronized static void init() { Preconditions.checkState(! hadInit, StringUtil.format("[{}]只能加载一次!", ConfigAdapter.class.getSimpleName())); Preconditions.checkState(compositeConfig.getConfigurations().size() > 1, StringUtil.format("[{}]没有加载任何配置", ConfigAdapter.class.getSimpleName())); if (! ConfigurationManager.isConfigurationInstalled()) { ConfigurationManager.install(compositeConfig); Preconditions.checkState(ConfigurationManager.isConfigurationInstalled(), StringUtil.format("[{}]加载失败!", ConfigAdapter.class.getSimpleName())); } Iterable<String> configurationNames = Iterables.transform(compositeConfig.getConfigurations(), new Function<AbstractConfiguration, String>() { @Nullable @Override public String apply(AbstractConfiguration input) { return input.getClass().getSimpleName(); } }); ConfigurationLog.successInit(ConfigAdapter.class, getAll()); hadInit = true;}
获取值
public static DynamicBooleanProperty getDynamicBool(String key, boolean defaultValue) { return getFactory().getBooleanProperty(key, defaultValue); }private static DynamicPropertyFactory getFactory() { return DynamicPropertyFactory.getInstance(); }
注意
- 在设置的时刻获取配置,配置源不会随着System#properties里面的配置更新而更新
- 更新配置方法不会更新实际的property文件,仅仅为更新内存数据,重启后失效
- 微服务都从配置中心动态的读取配置信息,而配置中心又在从配置源同步配置,所以这里就很自然的出现了一个读写安全的问题,好消息是Archaius已经解决了这个问题,Archaius是线程安全的,读写可以并发进行。
个人介绍:
高广超:多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能互联网架构。
本文首发在 高广超的简书博客 转载请注明!
- Netflix Archaius 分布式配置管理依赖构件
- Netflix开源类库archaius(一)概述
- Netflix archaius动态配置工具使用
- Netflix开源类库archaius(一)概述
- zookeeper分布式配置管理
- zookeeper分布式配置管理
- 分布式配置管理平台-Disconf
- 分布式配置管理系统QConf
- 分布式配置管理平台 Disconf
- 分布式配置管理平台 Disconf
- 分布式配置管理平台Disconf
- 分布式配置管理平台Disconf
- 分布式配置管理平台Disconf
- 分布式配置管理平台
- 分布式配置管理平台
- 分布式配置管理平台
- 淘宝分布式配置管理服务Diamond
- 淘宝分布式配置管理服务Diamond
- Arduino在Mac系统下的配置说明
- 最大似然函数
- 微服务学习笔记系列-Spring Cloud优质项目推荐
- 汇编语言第七章学习笔记——更灵活的定位内存地址的方法
- 函数
- Netflix Archaius 分布式配置管理依赖构件
- 线程学习
- 6.17
- 后台监测程序关闭时执行代码
- 互联网技术栈 『Contents Catalog』
- 习题4(4.3)
- MVP操作RecyclerView多条目SpringView,OKHttp封装请求网络
- 2017.11.04【NOIP提高组】模拟赛B组
- regular expression matching --python