公司有几个邮件发送平台,邮件发送网关参数配置都相同,各邮件发送平台维护相同的参数配置,每次邮件发送策略调整,需要改相应的参数,各邮件发送平台都需要修改各自的配置文件,然后重新发版,很不灵活。最后公司采用集中配置管理,引入zookeeper
基本思路:
app应用启动时候,读取zookeeper中节点/config/app/systemcfg配置信息、解析并缓存到map中,同时监听/config/app/systemcfg数据的变化,如果变化重新读取信息更新到map中,代码片段如下:
public class SystemStartUp extends HttpServlet {
private static final long serialVersionUID = 1L;
public SystemStartUp() {
super();
}
public void init() throws ServletException {
ConfigManager.getInstance().init();
}
public void destroy() {
}
}
package com.sohu.sc.web.zkconfig;
import java.util.Map;
/**
* 配置管理
* <B>系统名称:</B><BR>
* <B>模块名称:</B><BR>
* <B>中文类名:</B><BR>
* <B>概要说明:</B><BR>
* @author bhz(xjmfc)
* @since 2020年5月27日
*/
public class ConfigManager {
private Map<String, String> configMap = null;
private String nodePath;
ConfigClient configClient = null;
private static ConfigManager manager=null;
public ConfigManager(String nodePath) {
configClient=new ConfigClient();
this.nodePath=nodePath;
}
public static ConfigManager getInstance(){
if(manager==null){
synchronized (ConfigManager.class) {
manager=new ConfigManager(ConfigUpdate.SYSTEM_CFG_PATH);
if (manager == null) {
manager =new ConfigManager(ConfigUpdate.SYSTEM_CFG_PATH);;
}
}
}
return manager;
}
public void init(){
configClient.init(nodePath, configMap);
}
public Map<String, String> getConfigMap() {
return configMap;
}
public void setConfigMap(Map<String, String> configMap) {
this.configMap = configMap;
}
}
package com.sohu.sc.web.zkconfig;
import java.util.Map;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
/**
* 监听数据节点的变化
* <B>系统名称:</B><BR>
* <B>模块名称:</B><BR>
* <B>中文类名:</B><BR>
* <B>概要说明:</B><BR>
* @author bhz(xjmfc)
* @since 2020年5月27日
*/
public class ConfigWatcher implements Watcher {
private Map<String, String> configHashMap;
private ZooKeeper zooKeeper;
public ConfigWatcher(Map<String, String> configHashMap, ZooKeeper zooKeeper) {
this.configHashMap = configHashMap;
this.zooKeeper = zooKeeper;
}
@Override
public void process(WatchedEvent watchedEvent) {
try {
String config = new String(zooKeeper.getData(watchedEvent.getPath(), new ConfigWatcher(configHashMap, zooKeeper), null));
configHashMap=Utils.parseConfig(config);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.sohu.sc.web.zkconfig;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
* 获取节点配置信息,缓存起来
* <B>系统名称:</B><BR>
* <B>模块名称:</B><BR>
* <B>中文类名:</B><BR>
* <B>概要说明:</B><BR>
* @author bhz(xjmfc)
* @since 2020年5月27日
*/
public class ConfigClient implements Watcher {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zooKeeper = null;
private String nodePath;
public ConfigClient() {
}
public void init(String nodePath, Map<String, String> map) {
this.nodePath = nodePath;
try {
zooKeeper = new ZooKeeper("10.9.102.95:2181", 5000, new ConfigClient());
countDownLatch.await();
String config = new String(zooKeeper.getData(this.nodePath, new ConfigWatcher(map, zooKeeper), null));
map=Utils.parseConfig(config);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getType() ==
Event.EventType.None && watchedEvent.getState() == Event.KeeperState.SyncConnected) {
countDownLatch.countDown();
}
}
}
package com.sohu.sc.web.zkconfig;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
*
* <B>系统名称:</B><BR>
* <B>模块名称:</B><BR>
* <B>中文类名:</B><BR>
* <B>概要说明:</B><BR>
* @author bhz(xjmfc)
* @since 2020年5月27日
*/
public class ConfigUpdate implements Watcher {
public static String ROOT_PATH = "/config";
public static String APP_ZK_PATH = "/app";
public static String SYSTEM_CFG_PATH = ROOT_PATH + APP_ZK_PATH +"/systemcfg";
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zooKeeper = null;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper("10.9.102.95:2181", 5000, new ConfigUpdate());
countDownLatch.await();
String config = "adFlagLocation=1|FixedSender=1";
if (zooKeeper.exists(SYSTEM_CFG_PATH, false) == null) {
zooKeeper.create(SYSTEM_CFG_PATH, config.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} else {
zooKeeper.setData(SYSTEM_CFG_PATH, config.getBytes(), -1);
}
}
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
countDownLatch.countDown();
}
}
}
https://web.sendcloud.net