配置之痛与解决之道
当有很多项目需要你来不停的向集成,测试和生产环境发时, 配置文件的差异性会造成很大的困挠.
一方面你不希望把敏感信息到处保存. 另一方面会大量的地址信息,url,api-key,username/password需要配置. 每个引入的第三方api都需要配置, 往往不同环境的还都不一样. 一旦搞错了,轻则项目起不来,重则数据搞乱. 总之,头疼得很.
把这一切交给zookeeper, 让项目只有zookeeper的连接,其他找zookeeper要, 不失为一个解决办法.
如果将zookeeper写入hosts文件或dns服务, 则完全有可能实现应用零配置发布. 而zookeeper有完整的分布管理,权限管理等解决方案, 真正的开箱可用.
commons-configuration介绍
项目主页
commons-configuration包解决的是项目配置参数集中管理的问题.
配置参数可能来自于不同渠道,操作系统环境变量,JVM启动参数,各种配置文件,数据库,web.xml中的应用初始化参数和servlet初始参数等等. 通过统的一接口,为应用程序屏避这个细节上的差异,同时保持多种渠道完成应用配置的灵活性.同时增加缓存功能, 减少参数获取的时间延迟.
cofiguration接口实现类的继承关系
commons-configuration-zookeeper扩展介绍
github上有三个类似的项目
针对的是不同版本的commons-configuration
扩展模块主页
与commons-configuration 1.10整合, 本文以此为例.
简单整合
这个只接实现的Configuration接口,把节点路径做为key,节点data做为value.
可以对属性进行回写,支持不同数据类型,是一个不错的轻量级的方案.缺点是不能对zookeeper数据修改做出反应.
commons-configuration2.0整合
这个项目master上没有发布,develope分支上有代码,没有构建好的库到maven库.
直接使用会有些不方便.
pudn上也有一个 http://www.pudn.com/Download/...
但没有积分了, 下载不下来,也就当没看见了.
扩展以zookeeper的数据树为来源,看成类似的分布式的文件系统,读取某个节点的数据,
通过Properties的文本键值对格式或XML格式进行解析并缓存在内存中, 在远程数据没有变化时,后续的getProperty读取的是本地缓存,如果远程数据发生改变, 缓存会触发更新,后续读取getProperty会得到新的数据.
值得说明的是setProperty与getProperty并不对称. 你设置的值仅在本地缓存里发生改变,并没有真正持久化到远程的zookeeper.这与DatabaseConfiguration的行为是不一样的,只有DatabaseConfiguration是真正持久化的.
通过zookeeper获得动态属性与Spring进行整合
为spring bean的PropertyPlaceHolder赋值
可以硬编码实现,但这样显然不好 ;), 但好处是少引入两个包(spring-context, spring-context-support),因为不需要ApplicationContext, 只要BeanFactory即可.
Properties p = Config.getZooProperties(ZK_CONFIG_SPRING_PATH); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setProperties(p); cfg.postProcessBeanFactory(m_oXMLlBeanFactory);
可以用注解的方式, 但对spring3.1的项目不太友好.
XML是经典的方式, 让我们来试试
先定义的个类,继承BeanFactoryPostProcessor
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { private static final String ZK_CONFIG_SPRING_PATH="default"; private String path=ZK_CONFIG_SPRING_PATH; public void setPath(String path){this.path=path;} @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Properties p = Config.getZooProperties(path); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setProperties(p); cfg.postProcessBeanFactory(beanFactory); } }
再在XML声明一行
<bean id="myBeanFactoryPostProcessor" class="com.ssll.MyBeanFactoryPostProcessor" > <property name="path" value="custompath" /> </bean>
这样做的好处是path变得可配置. 而不是硬编码进去,在同时运行多个应用时,易于解决冲突问题.
可视化工具zookeeper-inspector
这个也有几个不同的版本
我用的是这个
https://github.com/zzhang5/zo...
虽然在github上星多,但也是有几年没有更新了,还好,对我的一些需求来说足够好了.
可以可视化展示所有节点和数据,能编辑修改文本节点和数据. 遗憾的是没有备份和恢复功能.
下载后通过maven构建一下就可以用了.
不过有个小问题就是新版本的Mac OS (High Sierra / Java 8)下Java路径判断有问题
把pom.xml中的appassemble-maven-plugin的版本升级至2.0.0就可以了
diff --git a/pom.xml b/pom.xml index 9e80d00..26b38be 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> - <version>1.1.1</version> + <version>2.0.0</version> <configuration> <binFileExtensions> <unix>.sh</unix>
备份与维护
zookeeper官方说法是拷贝datadir下的文件和binlog日志. 我也没有找到太好的方法, 谁知道给留个言.
项目源码
说了半天,没有源码就太不厚道了. 所以呢, 猛击此处下载 , 加不加星,就不强求了, 但有bug一定要反馈哟!