package com.snowcattle.game.service.rpc.server.zookeeper; import com.snowcattle.game.service.rpc.server.RpcConfig; import com.snowcattle.game.common.config.GameServerConfig; import com.snowcattle.game.common.config.GameServerConfigService; import com.snowcattle.game.common.config.GameServerDiffConfig; import com.snowcattle.game.common.config.ZooKeeperConfig; import com.snowcattle.game.common.constant.GlobalConstants; import com.snowcattle.game.common.constant.Loggers; import com.snowcattle.game.common.constant.ServiceName; import com.snowcattle.game.common.util.StringUtils; import com.snowcattle.game.manager.LocalMananger; import com.snowcattle.game.service.IService; import com.snowcattle.game.service.rpc.server.SdRpcServiceProvider; import org.apache.zookeeper.*; import org.apache.zookeeper.data.Stat; import org.slf4j.Logger; import org.springframework.stereotype.Service; import java.util.concurrent.CountDownLatch; /** * Created by jiangwenping on 17/3/30. * 注册自己到zookeeper */ @Service public class ZookeeperRpcServiceRegistry implements IService{ private static final Logger logger = Loggers.rpcLogger; private CountDownLatch countDownLatch = new CountDownLatch(1); private ZooKeeper zk; public void registerZooKeeper(){ if(zk == null){ zk = connectServer(); } } public void register(String registry_path, String nodePath, String nodeData){ if(!StringUtils.isEmpty(registry_path)){ if (zk != null) { addRootNode(zk, registry_path); try { if(zk.exists(nodePath, false) != null) { deleteNode(zk, nodePath); } } catch (KeeperException e) { // e.printStackTrace(); } catch (InterruptedException e) { // e.printStackTrace(); } createNode(zk, nodePath, nodeData); } } } /** * 链接zookeeper * @return */ private ZooKeeper connectServer(){ ZooKeeper zk = null; try { GameServerConfigService gameServerConfigService = LocalMananger.getInstance().getLocalSpringServiceManager().getGameServerConfigService(); ZooKeeperConfig zooKeeperConfig = gameServerConfigService.getZooKeeperConfig(); String registryAdress = zooKeeperConfig.getProperty(GlobalConstants.ZooKeeperConstants.registryAdress); zk = new ZooKeeper(registryAdress, GlobalConstants.ZooKeeperConstants.ZK_SESSION_TIMEOUT, new Watcher() { @Override public void process(WatchedEvent event) { countDownLatch.countDown(); } }); }catch (Exception e){ logger.error(e.toString(), e); } return zk; } private void addRootNode(ZooKeeper zk, String registry_path){ try{ Stat s = zk.exists(registry_path, false); if (s == null){ createRootNode(registry_path, new byte[0]); } }catch (Exception e){ logger.error(e.toString(), e); } } private void createNode(ZooKeeper zk ,String nodePath, String nodeData){ try { byte[] bytes = nodeData.getBytes(); String path = create(nodePath, bytes); logger.debug("create zookeeper node ({} => {})", path, bytes); }catch (Exception e){ logger.error(e.toString(), e); } } /** * *<b>function:</b>创建持久态的znode,比支持多层创建.比如在创建/parent/child的情况下,无/parent.无法通过 *@author cuiran *@createDate 2013-01-16 15:08:38 *@param path *@param data *@throws KeeperException *@throws InterruptedException */ public String createRootNode(String path,byte[] data) throws Exception{ /** * 此处采用的是CreateMode是PERSISTENT 表示The znode will not be automatically deleted upon client's disconnect. * EPHEMERAL 表示The znode will be deleted upon the client's disconnect. */ return this.zk.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } /** * *<b>function:</b>创建持久态的znode,比支持多层创建.比如在创建/parent/child的情况下,无/parent.无法通过 *@author cuiran *@createDate 2013-01-16 15:08:38 *@param path *@param data *@throws KeeperException *@throws InterruptedException */ public String create(String path,byte[] data) throws Exception{ /** * 此处采用的是CreateMode是PERSISTENT 表示The znode will not be automatically deleted upon client's disconnect. * EPHEMERAL 表示The znode will be deleted upon the client's disconnect. */ return this.zk.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); } public void deleteNode(ZooKeeper zk, String nodePath){ try { zk.delete(nodePath, -1); logger.debug("delete zookeeper node pathc ({} => {})", nodePath); }catch (Exception e){ logger.error(e.toString(), e); } } public ZooKeeper getZk() { return zk; } public void setZk(ZooKeeper zk) { this.zk = zk; } @Override public String getId() { return ServiceName.ZookeeperRpcServiceRegistry; } @Override public void startup() throws Exception { GameServerConfigService gameServerConfigService = LocalMananger.getInstance().getLocalSpringServiceManager().getGameServerConfigService(); GameServerDiffConfig gameServerDiffConfig = gameServerConfigService.getGameServerDiffConfig(); if(gameServerDiffConfig.isZookeeperFlag()) { registerZooKeeper(); registerNode(); } } public void registerNode() throws Exception{ GameServerConfigService gameServerConfigService = LocalMananger.getInstance().getLocalSpringServiceManager().getGameServerConfigService(); RpcConfig rpcConfig = gameServerConfigService.getRpcConfig(); SdRpcServiceProvider sdRpcServiceProvider = rpcConfig.getSdRpcServiceProvider(); GameServerConfig gameServerConfig = gameServerConfigService.getGameServerConfig(); String serverId = gameServerConfig.getServerId(); String host = gameServerConfig.getRpcBindIp(); String ports = gameServerConfig.getRpcPorts(); if(sdRpcServiceProvider.isWorldOpen()){ ZooKeeperNodeInfo zooKeeperNodeInfo = new ZooKeeperNodeInfo(ZooKeeperNodeBoEnum.WORLD, serverId, host, ports); register(zooKeeperNodeInfo.getZooKeeperNodeBoEnum().getRootPath(), zooKeeperNodeInfo.getNodePath(), zooKeeperNodeInfo.serialize()); } if(sdRpcServiceProvider.isGameOpen()){ ZooKeeperNodeInfo zooKeeperNodeInfo = new ZooKeeperNodeInfo(ZooKeeperNodeBoEnum.GAME, serverId, host, ports); register(zooKeeperNodeInfo.getZooKeeperNodeBoEnum().getRootPath(), zooKeeperNodeInfo.getNodePath(), zooKeeperNodeInfo.serialize()); } if(sdRpcServiceProvider.isDbOpen()){ ZooKeeperNodeInfo zooKeeperNodeInfo = new ZooKeeperNodeInfo(ZooKeeperNodeBoEnum.DB, serverId, host, ports); register(zooKeeperNodeInfo.getZooKeeperNodeBoEnum().getRootPath(), zooKeeperNodeInfo.getNodePath(), zooKeeperNodeInfo.serialize()); } } @Override public void shutdown() throws Exception { if(zk != null){ try { zk.close(); }catch (Exception e){ logger.error(e.toString(), e); } } } }