zookeeper実戦のサービス登録と発見
zookeeper適用シーン
zk適用シーンを振り返る:データ公開と購読 サービス登録と発見 分散ロック 分散キュー マスター選挙 配置センタ ネーミングサービス 負荷等化 zookeeperはサービス登録と発見を実現する
サービスの登録と検出
サービス登録と発見におけるzkの応用を見てみましょう.
コード実装ロジック:
サービス登録:
検出サービス:
もういくつかのポイントを話します.サービスを登録するときは一時ノードを作成する必要があり、接続を切断するときはサービス側が掛けた後にノードを削除して監視できる2.サービスを登録するときに作成するのは順序ノードであり、一般的に同じサービスは何台かのマシンがあり、作成順序ノードは複数のマシンのサービスを区別することができる.検出サービスの一端は、サービスノードのサブノードをリスニングし、サブノードが削除されたり、新しいサブノードが作成されたり、サービスが利用可能なマシンを再検出したりします.
dubboにおけるzkベースのサービス登録と発見もこの原理である
zk適用シーンを振り返る:
サービスの登録と検出
サービス登録と発見におけるzkの応用を見てみましょう.
コード実装ロジック:
サービス登録:
public class ServiceRegister {
private static final String BASE_SERVICES = "/services";
private static final String SERVICE_NAME="/products";
public static void register(String address,int port) {
try {
ZooKeeper zooKeeper = new ZooKeeper("localhost:2181",5000,(watchedEvent)->{});
Stat exists = zooKeeper.exists(BASE_SERVICES + SERVICE_NAME, false);
if(exists==null) {
zooKeeper.create(BASE_SERVICES + SERVICE_NAME,"".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
String server_path = address+":"+port;
//
// ,
zooKeeper.create(BASE_SERVICES + SERVICE_NAME+"/child",server_path.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(" ");
} catch (Exception e) {
e.printStackTrace();
}
}
}
検出サービス:
public class InitListener implements ServletContextListener {
private static final String BASE_SERVICES = "/services";
private static final String SERVICE_NAME="/products";
private ZooKeeper zooKeeper;
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
zooKeeper = new ZooKeeper("localhost:2181",5000,(watchedEvent)->{
if(watchedEvent.getType() == Watcher.Event.EventType.NodeChildrenChanged && watchedEvent.getPath().equals(BASE_SERVICES+SERVICE_NAME)) {
updateServiceList();
}
});
updateServiceList();
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateServiceList() {
try{
List children = zooKeeper.getChildren(BASE_SERVICES + SERVICE_NAME, true);
List newServerList = new ArrayList();
for(String subNode:children) {
byte[] data = zooKeeper.getData(BASE_SERVICES + SERVICE_NAME + "/" + subNode, false, null);
String host = new String(data, "utf-8");
System.out.println("host:"+host);
newServerList.add(host);
}
// ip , rpc
LoadBalance.SERVICE_LIST = newServerList;
}catch (Exception e) {
e.printStackTrace();
}
}
}
public abstract class LoadBalance {
public volatile static List SERVICE_LIST;
public abstract String choseServiceHost();
}
/**
*
*/
public class RamdomLoadBalance extends LoadBalance {
@Override
public String choseServiceHost() {
String result = "";
if(!CollectionUtils.isEmpty(SERVICE_LIST)) {
int index = new Random().nextInt(SERVICE_LIST.size());
result = SERVICE_LIST.get(index);
}
return result ;
}
}
もういくつかのポイントを話します.サービスを登録するときは一時ノードを作成する必要があり、接続を切断するときはサービス側が掛けた後にノードを削除して監視できる2.サービスを登録するときに作成するのは順序ノードであり、一般的に同じサービスは何台かのマシンがあり、作成順序ノードは複数のマシンのサービスを区別することができる.検出サービスの一端は、サービスノードのサブノードをリスニングし、サブノードが削除されたり、新しいサブノードが作成されたり、サービスが利用可能なマシンを再検出したりします.
dubboにおけるzkベースのサービス登録と発見もこの原理である