日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ZooKeeper学习笔记—配置管理

發(fā)布時間:2025/3/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ZooKeeper学习笔记—配置管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??

? ? 最近在工作中,為了完善公司集群服務(wù)的架構(gòu),提高可用性,降低運維成本,因此開始學(xué)習(xí)ZooKeeper。
? ? 至于什么是ZooKeeper?它能做什么?如何安裝ZooKeeper?我就不一一介紹了,類似這些資料網(wǎng)上到處都是。我主要是把在開發(fā)過程中,以及個人對ZooKeeper的一些了解記錄下來,大家如果遇到類似場景時,希望我的文章能夠給你提供一些思路。

? ? 我使用的ZooKeeper(以下簡稱:ZK)客戶端是Curator Framework,是Apache的項目,它主要的功能是為ZK的客戶端使用提供了高可用的封裝。在Curator Framework基礎(chǔ)上封裝的curator-recipes,實現(xiàn)了很多經(jīng)典場景。比如:集群管理(Leader選舉)、共享鎖、隊列、Counter等等。可以總結(jié)Curator主要解決以下三類問題:
  • 封裝ZK Client與Server之間的連接處理;?
  • 提供了一套Fluent風(fēng)格的操作API;?
  • 提供ZK各種應(yīng)用場景的抽象封裝;

? ?本文主要完成的目標(biāo)是:Spring PropertyPlaceholderConfigurer配置文件加載器集成ZooKeeper來實現(xiàn)遠(yuǎn)程配置讀取。

? ? 配置管理(Configuration Management)。
? ? 在集群服務(wù)中,可能都會遇到一個問題:那就是當(dāng)需要修改配置的時候,必須要對每個實例都進(jìn)行修改,這是一個很繁瑣的事情,并且易出錯。當(dāng)然可以使用腳本來解決,但這不是最好的解決辦法。

OK,Let's go!

我們先看看項目結(jié)構(gòu)



ZooKeeperPropertyPlaceholderConfigurer.java

繼承org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,重寫processProperties(beanFactoryToProcess, props)來完成遠(yuǎn)端配置加載的實現(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中包含=、忽略#號開頭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; }



Startup.java

程序啟動入口


package org.bigmouth.common.zookeeper.config;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Startup {public static void main(String[] args) {new ClassPathXmlApplicationContext("classpath:/config/applicationContext.xml");}}




ZooKeeperConfig.java

配置操作接口ZooKeeper的實現(xiàn)


package org.bigmouth.common.zookeeper.config;import org.apache.curator.framework.CuratorFramework; import org.apache.zookeeper.data.Stat;public class ZooKeeperConfig implements Config {@Overridepublic byte[] getConfig(String path) throws Exception {CuratorFramework client = ZooKeeperFactory.get();if (!exists(client, path)) {throw new RuntimeException("Path " + path + " does not exists.");}return client.getData().forPath(path);}private boolean exists(CuratorFramework client, String path) throws Exception {Stat stat = client.checkExists().forPath(path);return !(stat == null);}}




ZooKeeperFactory.java

管理ZooKeeper客戶端連接


package org.bigmouth.common.zookeeper.config;import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry;public class ZooKeeperFactory {public static final String CONNECT_STRING = "172.16.3.42:2181,172.16.3.65:2181,172.16.3.24:2181";public static final int MAX_RETRIES = 3;public static final int BASE_SLEEP_TIMEMS = 3000;public static final String NAME_SPACE = "cfg";public static CuratorFramework get() {RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIMEMS, MAX_RETRIES);CuratorFramework client = CuratorFrameworkFactory.builder().connectString(CONNECT_STRING).retryPolicy(retryPolicy).namespace(NAME_SPACE).build();client.start();return client;} }


applicationContext.xml

配置加載器使用我們自己創(chuàng)建的ZooKeeperPropertyPlaceholderConfigurer,因為它重寫了processProperties方法。這個方法里會去讀取遠(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

項目配置文件,里面除了配置ZooKeeper服務(wù)器地址和讀取的節(jié)點以外,其他所有的配置都應(yīng)該保存在ZooKeeper中。

zoo.paths=/properties

設(shè)置ZooKeeper數(shù)據(jù)

登錄ZooKeeper中為節(jié)點?/cfg/properties?添加一條配置項:


如圖所示:我創(chuàng)建了一個節(jié)點 /cfg/properties 并設(shè)置內(nèi)容為:jdbc.driver=org.postgresql.Driver

運行Startup.java

OK 了,zoo.paths是本地application.properties文件中的,jdbc.driver是遠(yuǎn)程ZooKeeper服務(wù)器中的。


項目中需要依賴的jar包


<dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.4</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>3.0.3.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.0.3.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>3.0.3.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>3.0.3.RELEASE</version> </dependency><!-- ZooKeeper --> <dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.6</version> </dependency> <dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.4.2</version> </dependency> <dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.4.2</version> </dependency>

相關(guān)資料:

Apache Curator Framework

Apache ZooKeeper



博主,問個zk值被刷了的問題。

假設(shè),我們現(xiàn)在配置的數(shù)據(jù),都是從zk中獲取的,但是某個值被刷新了,我們有個watch監(jiān)控到了,但是這個值怎么刷入到內(nèi)存中,或者說重新注冊那個bean?

有沒有這方面的解決思路,我有點迷惑

ZKClient 可以輕松監(jiān)聽到配置什么時候變化,但變化后該怎么做?
如果你用了spring,或許這篇文章能幫到你:https://github.com/jamesmorgan/ReloadablePropertiesAnnotation

轉(zhuǎn)載于:https://my.oschina.net/boltwu/blog/464149

總結(jié)

以上是生活随笔為你收集整理的ZooKeeper学习笔记—配置管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。