zookeeper 监听存活节点
---------------------
作者:踏海寻天
来源:CSDN
原文:https://blog.csdn.net/u011066435/article/details/78158357
版权声明:本文为博主原创文章,转载请附上博文链接!
应用场景,公司服务器不想做负载均衡,但又担心单点故障的情况发生,于是将服务器资源注册到zookeeper中,客户端从zookeeper中动态获取服务器资源,然后通过资源进行访问,可以注册多个服务器资源到zookeeper,客户端监听zookeeper中的服务资源,当服务端有故障,比如服务当机,则zookeeper中的资源因为长连接断开而自动移除资源,同时客户端的资源会自动重载过滤,达到自动选择存活节点的目的。
注意事项:
1:创建节点时,需要创建临时节点ephemeral,session失效时间要按需求设置,session失效时间默认为30秒。
2:创建节点时,先删除此节点。
实现代码如下:
[Java]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | public interface ZkConfig { /** * 配置平台根节点名称 */ static String root = "/server_node"; /** * 初始化配置 */ void init(); /** * 重新加载配置资源 */ void reload(); /** * 添加配置 * @param key * @param value */ void add(String key, String value); /** * 更新配置 * @param key * @param value */ void update(String key, String value); /** * 删除配置 * @param key */ void delete(String key); /** * 获取配置 * @param key * @return */ String get(String key); /** * 获取所有的配置内容 * @return */ Map<String, String> getAll();} |
监听实现
[Java]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | public class ZkWatcher { private ZkClient client; private ZkListener zkListener; private ZkConfig zkConfig ; public ZkWatcher(ZkClient client, ZkConfig zkConfig) { this.client = client; this.zkConfig = zkConfig ; this.initConfig(); } private void initConfig(){ zkListener = new ZkListener(); } public void watcher(String key){ client.subscribeDataChanges(key, configYardListener); client.subscribeChildChanges(key, configYardListener); } /** * 配置监听器 * @author flyking * */ private class ZkListener implements IZkDataListener,IZkChildListener{ public void handleDataChange(String dataPath, Object data) throws Exception { System.out.println("data "+dataPath+" change,start reload configProperties"); configYard.reload(); } public void handleDataDeleted(String dataPath) throws Exception { System.out.println("data "+dataPath+" delete,start reload configProperties"); configYard.reload(); } public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception { System.out.println("data "+parentPath+" ChildChange,start reload configProperties"); ZkConfig.reload(); } }} |
接口方法实现
[AppleScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | public class ZkConfigImpl implements ZkConfig { /** * 存储配置内容 */ private volatile Map<String, String> zkProperties = new HashMap<String, String>(); private ZkClient client; private ZkWatcher zkWatcher ; public ZkConfigImpl(String serverstring) { this.client = new ZkClient(serverstring, 300, 3000); zkWatcher = new ZkWatcher(client,this); this.init(); } /** * 初始化加载配置到内存 */ public void init() { if(!client.exists(root)){ client.createEphemeral(root); } if (zkProperties == null) { System.out.println("start to init zkProperties"); zkProperties = this.getAll(); System.out.println("init zkProperties over"); } } private String contactKey(String key){ return root.concat("/").concat(key); } public void add(String key, String value) { String contactKey = this.contactKey(key); this.client.createEphemeral(contactKey, value); zkWatcher.watcher(contactKey); } public void update(String key, String value) { String contactKey = this.contactKey(key); this.client.writeData(contactKey, value); zkWatcher.watcher(contactKey); } public void delete(String key) { String contactKey = this.contactKey(key); this.client.delete(contactKey); } public String get(String key) { if(this.zkProperties.get(key) == null){ String contactKey = this.contactKey(key); if(!this.client.exists(contactKey)){ return null; } return this.client.readData(contactKey); } return zkProperties.get(key); } public Map<String, String> getAll() { if(zkProperties != null){ return zkProperties; } List<String> list = this.client.getChildren(root); Map<String, String> currentProperties = new HashMap<String, String>(); for(String zk : list){ String value = this.client.readData(zk); String key = zk.substring(zk.indexOf("/")+1); currentProperties.put(key, value); } return zkProperties; } public void reload() { List<String> list = this.client.getChildren(root); Map<String, String> currentProperties = new HashMap<String, String>(); for(String zk : list){ String value = this.client.readData(this.contactKey(zk)); System.out.println(zk +"========="+value); currentProperties.put(zk, value); } zkProperties = currentProperties; }} |
测试
[Java]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | public static void main(String[] args) { ZkConfigImpl zk = new ZkConfigImpl ("192.168.41.128:2181"); zk.add("server1", "192.168.1.101:1101"); zk.add("server2", "192.168.1.101:1102"); System.out.println("value is===>"+zk.get("server1")); System.out.println("value is===>"+zk.get("server2")); yard.update("server1", "192.168.9.109:8080"); System.out.println("update server1 value is===>"+zk.get("server1")); yard.delete("server1"); yard.delete("server2"); }} |
---------------------
作者:踏海寻天
来源:CSDN
原文:https://blog.csdn.net/u011066435/article/details/78158357
版权声明:本文为博主原创文章,转载请附上博文链接!
更多资讯可关注:gzitcast