Netflix Archaius 分布式配置管理依赖构件

Archaius 配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。

概述

archaius是Netflix公司开源项目之一,基于java的配置管理类库,主要用于多配置存储的动态获取。主要功能是对apache common configuration类库的扩展。在云平台开发中可以将其用作分布式配置管理依赖构件。同时,它有如下一些特性:

  • 动态类型化属性
  • 高效和线程安全的配置操作
  • 配置改变时的回调机制
  • 轮询框架
  • JMX,通过Jconsole检查和调用操作属性
  • 组合配置

image.png

适用场景

对于传统的单体应用,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是线程安全的,读写可以并发进行。

个人介绍:

高广超:多年一线互联网研发与架构设计经验,擅长设计与落地高可用、高性能互联网架构。

本文首发在 高广超的简书博客 转载请注明!

时间: 2024-10-12 04:47:54

Netflix Archaius 分布式配置管理依赖构件的相关文章

使用spring cloud实现分布式配置管理

<7天学会spring cloud系列>之创建配置管理服务器及实现分布式配置管理应用. 本文涉及到的项目: 开源项目:http://git.oschina.net/zhou666/spring-cloud-7simple cloud-config-repo:配置文件存放的文件夹 cloud-simple-service:一个使用mybatis的数据库应用 分布式配置管理应该是分布式系统和微服务应用的第一步.想象一下如果你有几十个服务或应用需要配置,而且每个服务还分为开发.测试.生产等不同维度的

分布式配置管理平台——xxl-cfg(业余时间写的,完善中)

前提: 一般情况下,web项目的resource目录下,通常会配置一堆的properties配置文件或txt配置文件等等,例如jdbc.mail.memcached.redis和业务所需的属性配置文件等等. 但是,在集群环境,配置变更时,会导致两个问题: 1.需要修改每个集群节点下项目的配置文件,甚至需要重新编译打包: 2.需要重启服务器: 3.RD/QA/PRODUCTION,各个环境通常需要维护不同的配置: 此文主要是为了解决上述几个问题,在分布式环境中,统一管理项目配置文件: 简介:xxl

淘宝分布式配置管理服务Diamond

在一个分布式环境中,同类型的服务往往会部署很多实例.这些实例使用了一些配置,为了更好地维护这些配置就产生了配置管理服务.通过这个服务可以轻松地管理这些应用服务的配置问题.应用场景可概括为: zookeeper的一种应用就是分布式配置管理(基于ZooKeeper的配置信息存储方案的设计与实现).百度也有类似的实现:disconf. Diamond则是淘宝开源的一种分布式配置管理服务的实现.Diamond本质上是一个Java写的Web应用,其对外提供接口都是基于HTTP协议的,在阅读代码时可以从实现

disconf-web 分布式配置管理平台

disconf-web 分布式配置管理平台1.安装mysql2.tomcat3.安装nginx4.安装zookeeper5.安装redis6.下载disconf安装包(1)下载disconf包git clone https://github.com/knightliao/disconf.git (2)配置disconf配置文件 2.1 创建两个文件夹online-resources和war mkdir /usr/local/disconf/war #设置War包将要被部署的地址mkdir /us

分布式配置管理平台-disconf部署

应开发需要,搭建个简要的disconf环境. -------------------------------------------------- 参考:http://blog.csdn.net/zhu_tianwei/article/details/49512751 -------------------------------------------------- 系统环境:centos6.4 -------------------------------------------------

构建SpringBoot,SpringCloud微服务架构分布式电商项目实战

Spring Cloud 微服务总体架构图 上面图中技术名词理解: 1.Sleuth-链路跟踪 为服务之间调用提供链路追踪.通过Sleuth可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长.从而让我们可以很方便的理清各微服务间的调用关系. 2.断路器(Hystrix) 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务通常会集群

Spring cloud子项目

目前来说spring主要集中于spring boot(用于开发微服务)和spring cloud相关框架的开发,我们从几张图着手理解,然后再具体介绍: spring cloud子项目包括: Spring Cloud Config:配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储.Git以及Subversion. Spring Cloud Bus:事件.消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署. Sprin

【译文】用Spring Cloud和Docker搭建微服务平台

by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-microservices.html This blog series will introduce you to some of the foundational concepts of building a microservice-based platform using Spring Cloud

【微服务架构】SpringCloud组件和概念介绍(一)

一:什么是微服务(Microservice) 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及部署,并通过各自暴露的API接口相互通讯.它们彼此相互协作,作为一个整体为用户提供功能,却可以独立地进行扩. 微服务架构需要的功能或使用场景 1:我们把整个系统根据业务拆分成几个子系统. 2:每个子系统可以部署多个应用,多个应用之间使用负载均衡. 3:需要一个服务注册中心,所有的服务都在注册中心注册