Eng*_*_DJ 19 java service configuration spring apache-zookeeper
是否有任何记录良好的Apache ZooKeeper用例用于分发Java应用程序的配置,特别是Spring服务?
像许多云服务用户一样,我需要更改可变数量的Java服务的配置,最好是在运行时,而不需要重新启动服务.
UPDATE
最后,我最终写了一些东西,将ZooKeeper节点作为属性文件加载,并创建一个ResourcePropertySource并将其插入到Spring上下文中.请注意,这不会反映上下文启动后ZooKeeper节点的更改.
public class ZooKeeperPropertiesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final Logger logger = LoggerFactory.getLogger(ZooKeeperPropertiesApplicationContextInitializer.class);
private final CuratorFramework curator;
private String projectName;
private String projectVersion;
public ZooKeeperPropertiesApplicationContextInitializer() throws IOException {
logger.trace("Attempting to construct CuratorFramework instance");
RetryPolicy retryPolicy = new ExponentialBackoffRetry(10, 100);
curator = CuratorFrameworkFactory.newClient("zookeeper", retryPolicy);
curator.start();
}
/**
* Add a primary property source to the application context, populated from
* a pre-existing ZooKeeper node.
*/
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
logger.trace("Attempting to add ZooKeeper-derived properties to ApplicationContext PropertySources");
try {
populateProjectProperties();
Properties properties = populatePropertiesFromZooKeeper();
PropertiesPropertySource propertySource = new PropertiesPropertySource("zookeeper", properties);
applicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
logger.debug("Added ZooKeeper-derived properties to ApplicationContext PropertySources");
curator.close();
} catch (IOException e) {
logger.error("IO error attempting to load properties from ZooKeeper", e);
throw new IllegalStateException("Could not load ZooKeeper configuration");
} catch (Exception e) {
logger.error("IO error attempting to load properties from ZooKeeper", e);
throw new IllegalStateException("Could not load ZooKeeper configuration");
} finally {
if (curator != null && curator.isStarted()) {
curator.close();
}
}
}
/**
* Populate the Maven artifact name and version from a property file that
* should be on the classpath, with values entered via Maven filtering.
*
* There is a way of doing these with manifests, but it's a right faff when
* creating shaded uber-jars.
*
* @throws IOException
*/
private void populateProjectProperties() throws IOException {
logger.trace("Attempting to get project name and version from properties file");
try {
ResourcePropertySource projectProps = new ResourcePropertySource("project.properties");
this.projectName = (String) projectProps.getProperty("project.name");
this.projectVersion = (String) projectProps.getProperty("project.version");
} catch (IOException e) {
logger.error("IO error trying to find project name and version, in order to get properties from ZooKeeper");
}
}
/**
* Do the actual loading of properties.
*
* @return
* @throws Exception
* @throws IOException
*/
private Properties populatePropertiesFromZooKeeper() throws Exception, IOException {
logger.debug("Attempting to get properties from ZooKeeper");
try {
byte[] bytes = curator.getData().forPath("/distributed-config/" + projectName + "/" + projectVersion);
InputStream in = new ByteArrayInputStream(bytes);
Properties properties = new Properties();
properties.load(in);
return properties;
} catch (NoNodeException e) {
logger.error("Could not load application configuration from ZooKeeper as no node existed for project [{}]:[{}]", projectName, projectVersion);
throw e;
}
}
}
Run Code Online (Sandbox Code Playgroud)
你应该考虑Spring Cloud Config:
http://projects.spring.io/spring-cloud/
Spring Cloud Config由git存储库支持的集中式外部配置管理.配置资源直接映射到Spring,
Environment但如果需要,可以由非Spring应用程序使用.
源代码在这里:
https://github.com/spring-cloud/spring-cloud-config
此处的示例应用:
上周我参加了 James Strachen 的 Apache Camel 演讲,他提到在云中基于 Java 的服务器中使用 ZooKeeper作为配置信息的来源。
我看过 Adrian Colyer(SpringSource 的 CTO)关于 Spring 中运行时配置更改的演讲,但是 Spring 现在支持这一点吗?
在我看来,如果您从典型架构的 Spring 应用程序开始,我认为在其之上改造动态配置更改并不容易。
| 归档时间: |
|
| 查看次数: |
17823 次 |
| 最近记录: |