package com.hqyg.disjob.register.rpc; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; import org.springframework.stereotype.Service; import com.hqyg.disjob.register.repository.ZnodeApiCuratorImpl; import com.hqyg.disjob.register.repository.watch.WatchApiCuratorImpl; import com.hqyg.disjob.register.repository.watch.listener.ServerNodeListener; import com.hqyg.disjob.register.utils.RegisterUtils; import com.hqyg.disjob.register.utils.ZooKeeperRegistryUtils; import com.hqyg.disjob.rpc.client.HURL; /** * <pre> * File: ZookeeperRegistry.java * * Copyright (c) 2016, globalegrow.com All Rights Reserved. * * Description: * zoopkeeper的订阅和发现处理 * * Revision History * Date, Who, What; * 2016年5月12日 Disjob Initial. * </pre> */ @Service("zookeeperRegistry") public class ZookeeperRegistry extends FailbackRegistry { private CuratorFramework zkClient; private ZnodeApiCuratorImpl znode; private WatchApiCuratorImpl watchApiCuratorImpl; private ConcurrentHashMap<HURL, ConcurrentHashMap<NotifyListener, PathChildrenCacheListener>> urlListeners = new ConcurrentHashMap<HURL, ConcurrentHashMap<NotifyListener, PathChildrenCacheListener>>(); //因为zkClient统一管理,所以这里的zkclient是设置进来,后期改为直接从client池里获取 public void setZkClient(CuratorFramework zkClient) { this.zkClient = zkClient; } @PostConstruct public void init(){ } public ZookeeperRegistry(){ super(new HURL()); znode = new ZnodeApiCuratorImpl(); watchApiCuratorImpl = new WatchApiCuratorImpl(); } public ConcurrentHashMap<HURL, ConcurrentHashMap<NotifyListener, PathChildrenCacheListener>> getUrlListeners() { return urlListeners; } /** * 订阅服务和注册监听 */ @Override public void doSubscribe(final HURL url, final NotifyListener notifyListener) { ConcurrentHashMap<NotifyListener, PathChildrenCacheListener> childChangeListeners = urlListeners.get(url); if (childChangeListeners == null) { urlListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, PathChildrenCacheListener>()); childChangeListeners = urlListeners.get(url); } PathChildrenCacheListener zkChildListener = childChangeListeners.get(notifyListener); if (zkChildListener == null) { childChangeListeners.putIfAbsent(notifyListener, new ServerNodeListener(url, notifyListener)); zkChildListener = childChangeListeners.get(notifyListener); } // 防止旧节点未正常注销 removeNode(url, ZkNodeType.CONSUMER); createNode(url, ZkNodeType.CONSUMER); // 订阅server节点,并获取当前可用server String serverTypePath = RegisterUtils.toNodeTypePath(url, ZkNodeType.PROVIDER); List<String > currentChilds = watchApiCuratorImpl.pathChildrenWatch(zkClient, serverTypePath, false, zkChildListener); ZooKeeperRegistryUtils.notify(url, notifyListener, RegisterUtils.nodeChildsToUrls(zkClient, serverTypePath, currentChilds)); } @Override public void doUnsubscribe(HURL url, NotifyListener notifyListener) { } /** * client直接从服务端取URL对应的所有服务地址 */ @Override public List<HURL> doDiscover(HURL url) { try { String parentPath = RegisterUtils.toNodeTypePath(url, ZkNodeType.PROVIDER); List<String> currentChilds = new ArrayList<String>(); if (znode.checkExists(zkClient, parentPath)) { currentChilds = zkClient.getChildren().forPath(parentPath); } return RegisterUtils.nodeChildsToUrls(zkClient, parentPath, currentChilds); } catch (Throwable e) { throw new RuntimeException(String.format("Failed to discover %s from zookeeper(), cause: %s", url, e.getMessage())); } } @Override protected void doAvailable(HURL url) { } private void createNode(HURL url, ZkNodeType nodeType) { String nodeTypePath = RegisterUtils.toNodeTypePath(url, nodeType); if (!znode.checkExists(zkClient, nodeTypePath)) { znode.createPersistent(zkClient, nodeTypePath, true); } znode.createEphemeral(zkClient, RegisterUtils.toNodePath(url, nodeType), url.toFullStr()); } private void removeNode(HURL url, ZkNodeType nodeType) { String nodePath = RegisterUtils.toNodePath(url, nodeType); if (znode.checkExists(zkClient, nodePath)) { znode.deleteByZnode(zkClient, nodePath); } } @Override protected void doUnavailable(HURL url) { // TODO Auto-generated method stub } public void doRegister(HURL url) { // TODO Auto-generated method stub } }