package com.github.wangxuehui.rpc.snrpc.zookeeper.provider; import java.io.IOException; import java.util.concurrent.CountDownLatch; import com.github.wangxuehui.rpc.snrpc.conf.SnRpcConfig; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.ZooKeeper; import com.github.wangxuehui.rpc.snrpc.util.Const; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author skyim E-mail:wxh64788665@gmail.com * 类说明 */ public class ServiceProvider { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceProvider.class); private SnRpcConfig snRpcConfig = SnRpcConfig.getInstance(); // 用于等待 SyncConnected事件触发后继续执行当前线程 private CountDownLatch latch = new CountDownLatch(1); // 发布服务并注册 host,port 地址到 ZooKeeper中 public void publish(String host, int port) { String url = publishService(host, port); if (url != null) { ZooKeeper zk = connectServer(); if (zk != null) { createNode(zk, url); } } } // 发布服务 private String publishService(String host, int port) { String url = String.format("skyim:%s:%d", host, port); LOGGER.debug("publish service (url: {})", url); return url; } // 连接 ZooKeeper服务器 private ZooKeeper connectServer() { ZooKeeper zk = null; try { zk = new ZooKeeper(snRpcConfig.getProperty("snrpc.zookeeper.ip"), Const.ZK_SESSION_TIMEOUT, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.SyncConnected) { latch.countDown(); // 唤醒当前正在执行的线程 } } }); latch.await(); // 使当前线程处于等待状态 } catch (IOException | InterruptedException e) { LOGGER.error("", e); } return zk; } // 创建 ZNode private void createNode(ZooKeeper zk, String url) { try { byte[] data = url.getBytes(); String path = zk.create(Const.ZK_PROVIDER_PATH, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // 创建一个临时性且有序的 ZNode LOGGER.debug("create zookeeper node ({} => {})", path, url); } catch (KeeperException | InterruptedException e) { LOGGER.error("", e); } } }