ZooKeeper学习笔记—配置管理
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
? ? 最近在工作中,為了完善公司集群服務(wù)的架構(gòu),提高可用性,降低運(yùn)維成本,因此開(kāi)始學(xué)習(xí)ZooKeeper。? ? 至于什么是ZooKeeper?它能做什么?如何安裝ZooKeeper?我就不一一介紹了,類似這些資料網(wǎng)上到處都是。我主要是把在開(kāi)發(fā)過(guò)程中,以及個(gè)人對(duì)ZooKeeper的一些了解記錄下來(lái),大家如果遇到類似場(chǎng)景時(shí),希望我的文章能夠給你提供一些思路。
? ? 我使用的ZooKeeper(以下簡(jiǎn)稱:ZK)客戶端是Curator Framework,是Apache的項(xiàng)目,它主要的功能是為ZK的客戶端使用提供了高可用的封裝。在Curator Framework基礎(chǔ)上封裝的curator-recipes,實(shí)現(xiàn)了很多經(jīng)典場(chǎng)景。比如:集群管理(Leader選舉)、共享鎖、隊(duì)列、Counter等等。可以總結(jié)Curator主要解決以下三類問(wèn)題:
- 封裝ZK Client與Server之間的連接處理;?
- 提供了一套Fluent風(fēng)格的操作API;?
- 提供ZK各種應(yīng)用場(chǎng)景的抽象封裝;
? ?本文主要完成的目標(biāo)是:Spring PropertyPlaceholderConfigurer配置文件加載器集成ZooKeeper來(lái)實(shí)現(xiàn)遠(yuǎn)程配置讀取。
? ? 配置管理(Configuration Management)。? ? 在集群服務(wù)中,可能都會(huì)遇到一個(gè)問(wèn)題:那就是當(dāng)需要修改配置的時(shí)候,必須要對(duì)每個(gè)實(shí)例都進(jìn)行修改,這是一個(gè)很繁瑣的事情,并且易出錯(cuò)。當(dāng)然可以使用腳本來(lái)解決,但這不是最好的解決辦法。
OK,Let's go!
我們先看看項(xiàng)目結(jié)構(gòu)
ZooKeeperPropertyPlaceholderConfigurer.java
繼承org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,重寫processProperties(beanFactoryToProcess, props)來(lái)完成遠(yuǎn)端配置加載的實(shí)現(xiàn)
package org.bigmouth.common.zookeeper.config.spring;import java.io.UnsupportedEncodingException; import java.util.Properties;import org.apache.commons.lang.StringUtils; import org.bigmouth.common.zookeeper.config.Config; import org.bigmouth.common.zookeeper.config.ZooKeeperConfig; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;public class ZooKeeperPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {public static final String PATH = "zoo.paths";@Overrideprotected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)throws BeansException {super.processProperties(beanFactoryToProcess, props);try {fillCustomProperties(props);System.out.println(props);}catch (Exception e) {// Ignoree.printStackTrace();}}private void fillCustomProperties(Properties props) throws Exception {byte[] data = getData(props);fillProperties(props, data);}private void fillProperties(Properties props, byte[] data) throws UnsupportedEncodingException {String cfg = new String(data, "UTF-8");if (StringUtils.isNotBlank(cfg)) {// 完整的應(yīng)該還需要處理:多條配置、value中包含=、忽略#號(hào)開(kāi)頭String[] cfgItem = StringUtils.split(cfg, "=");props.put(cfgItem[0], cfgItem[1]);}}private byte[] getData(Properties props) throws Exception {String path = props.getProperty(PATH);Config config = new ZooKeeperConfig();return config.getConfig(path);}}
Config.java
配置操作接口? package org.bigmouth.common.zookeeper.config;public interface Config {byte[] getConfig(String path) throws Exception; }
程序啟動(dòng)入口
配置操作接口ZooKeeper的實(shí)現(xiàn)
管理ZooKeeper客戶端連接
applicationContext.xml
配置加載器使用我們自己創(chuàng)建的ZooKeeperPropertyPlaceholderConfigurer,因?yàn)樗貙懥藀rocessProperties方法。這個(gè)方法里會(huì)去讀取遠(yuǎn)程配置。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans><bean class="org.bigmouth.common.zookeeper.config.spring.ZooKeeperPropertyPlaceholderConfigurer"><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /><property name="ignoreResourceNotFound" value="true" /><property name="locations"><list><value>classpath:application.properties</value></list></property></bean></beans>
application.properties
項(xiàng)目配置文件,里面除了配置ZooKeeper服務(wù)器地址和讀取的節(jié)點(diǎn)以外,其他所有的配置都應(yīng)該保存在ZooKeeper中。
zoo.paths=/properties設(shè)置ZooKeeper數(shù)據(jù)
登錄ZooKeeper中為節(jié)點(diǎn)?/cfg/properties?添加一條配置項(xiàng):
如圖所示:我創(chuàng)建了一個(gè)節(jié)點(diǎn) /cfg/properties 并設(shè)置內(nèi)容為:jdbc.driver=org.postgresql.Driver
運(yùn)行Startup.java
OK 了,zoo.paths是本地application.properties文件中的,jdbc.driver是遠(yuǎn)程ZooKeeper服務(wù)器中的。
項(xiàng)目中需要依賴的jar包
相關(guān)資料:
Apache Curator FrameworkApache ZooKeeper
博主,問(wèn)個(gè)zk值被刷了的問(wèn)題。
假設(shè),我們現(xiàn)在配置的數(shù)據(jù),都是從zk中獲取的,但是某個(gè)值被刷新了,我們有個(gè)watch監(jiān)控到了,但是這個(gè)值怎么刷入到內(nèi)存中,或者說(shuō)重新注冊(cè)那個(gè)bean?
有沒(méi)有這方面的解決思路,我有點(diǎn)迷惑
ZKClient 可以輕松監(jiān)聽(tīng)到配置什么時(shí)候變化,但變化后該怎么做?如果你用了spring,或許這篇文章能幫到你:https://github.com/jamesmorgan/ReloadablePropertiesAnnotation
轉(zhuǎn)載于:https://my.oschina.net/boltwu/blog/464149
總結(jié)
以上是生活随笔為你收集整理的ZooKeeper学习笔记—配置管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iOS平台快速发布HT for Web拓
- 下一篇: secureFX上传文件的时候报错,se