1、Archaius是什么?
Archaius实际上是对Apache Common Configuration Library的一个封装和扩展,提供了一组基于Java的配置API,主要的特性包括:
- 配置可动态调整
- 配置支持类型(Int、Long、Boolean等)
- 高性能和线程安全
- 提供一个拉(pulling)配置的框架,可以从配置源动态拉取变更的配置
- 支持回调(callback)机制,在配置变更时自动调用
- 支持JMX MBean,可以通过JConsole查看配置和修改配置
Achaius的核心是一个称为组合配置(Composite Configuration)的概念,简单可以理解为一个分层级的配置,层级有优先级,高优先级的层级的配置会覆盖低优先级的配置。每一个层级可以从某个配置源获取配置,例如本地配置文件、JDBC数据源、远程REST API等。配置源还可以在运行时动态拉取变更,例如在上图中,持久化数据库配置(Persisted DB Configuration)是指将配置存在关系数据库中,相应的配置源会定期从数据库拉取变更。配置的最终值由顶级配置决定,例如,如果多个层级都含有某个配置项,那么应用最终见到的值是配置层级中最顶层的值。配置分层的顺序是可以调整的
拉配置核心接口为PolledConfigurationSource
,Achaius提供了两个子类:JDBCConfigurationSource(基于数据库)、URLConfigurationSource(基于URL),下面我们就以基于数据库的方式来获取动态属性
public interface PolledConfigurationSource {
/**
* Poll the configuration source to get the latest content.
*
* @param initial true if this operation is the first poll.
* @param checkPoint Object that is used to determine the starting point if the result returned is incremental.
* Null if there is no check point or the caller wishes to get the full content.
* @return The content of the configuration which may be full or incremental.
* @throws Exception If any exception occurs when fetching the configurations.
*/
public PollResult poll(boolean initial, Object checkPoint) throws Exception;
}
2、基于数据库获取动态属性
1)、添加archaius依赖
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.6.0</version>
</dependency>
2)、创建数据库表
CREATE TABLE `my_site_properties` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`property_key` varchar(50) DEFAULT NULL COMMENT '属性的key',
`property_value` varchar(255) DEFAULT NULL COMMENT '属性的值',
PRIMARY KEY (`id`),
UNIQUE KEY `my_site_properties_u1` (`property_key`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
3)、配置类
@Configuration
public class DynamicPropertyFactoryConfig {
@Autowired
private DataSource dataSource;
@PostConstruct
public void init() {
PolledConfigurationSource source = new JDBCConfigurationSource(dataSource,
"select distinct property_key, property_value from my_site_properties",
"property_key",
"property_value");
//首次任务立即执行,1秒间隔
FixedDelayPollingScheduler scheduler = new FixedDelayPollingScheduler(0, 1000, false);
DynamicConfiguration configuration = new DynamicConfiguration(source,
scheduler);
ConfigurationManager.install(configuration);
}
}
4)、获取动态配置
@RestController
@RequestMapping("/api/demo1")
public class Demo1Controller {
DynamicStringProperty defaultProp = DynamicPropertyFactory.getInstance().getStringProperty(
"demo", "default");
@GetMapping
public String getDynamicStringProperty() {
return defaultProp.getValue();
}
}
实现效果:请求该接口获取动态配置,返回结果为数据库中property_key为demo对应的property_value,更改数据库的值再次请求接口也能获取最新的值
3、自定义configuration source和polling scheduler
1)、自定义配置源
实现PolledConfigurationSource接口
public class DynamicConfigurationSource implements PolledConfigurationSource {
@Override
public PollResult poll(boolean initial, Object checkPoint) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("demo2", UUID.randomUUID().toString());
return PollResult.createFull(map);
}
}
如果要自定义定时调度器,实现抽象类AbstractPollingScheduler即可
2)、配置类
@Configuration
public class DynamicPropertyFactoryConfig {
@PostConstruct
public void init() {
PolledConfigurationSource source = new DynamicConfigurationSource();
//首次任务立即执行,1秒间隔 DynamicConfigurationSource中使用UUID 相当于demo2的配置每1秒刷新一次
FixedDelayPollingScheduler scheduler = new FixedDelayPollingScheduler(0, 1000, false);
DynamicConfiguration configuration = new DynamicConfiguration(source,
scheduler);
ConfigurationManager.install(configuration);
}
}
3)、获取动态配置
@RestController
@RequestMapping("/api/demo2")
public class Demo2Controller {
DynamicStringProperty defaultProp = DynamicPropertyFactory.getInstance().getStringProperty(
"demo2", "default");
@GetMapping
public String getDynamicStringProperty() {
return defaultProp.getValue();
}
}
实现效果:请求该接口获取动态配置,返回结果为UUID,每秒进行更换
参考:
https://blog.csdn.net/yang75108/article/details/86990136
https://github.com/Netflix/archaius/wiki
https://www.cnblogs.com/lexiaofei/p/7169483.html