自己设计一个的轻量级的RPC框架–服务端zookeeper的发现和注册
#前言
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。
常用场景
1.数据发布与订阅(配置中心)
2. 命名服务
3. 分布式协调服务/通知
4. Master选举
5. 分布式锁
本项目主要用zookeeper的数据发布与订阅
ZooKeeper java使用方法
建立连接
@Override
public void process(WatchedEvent event) {
if(event.getState()==KeeperState.SyncConnected){
System.out.println("连接成功");
countDownLatch.countDown();
}
}
public ZookeeperBase(String host) throws IOException, InterruptedException{
this.zookeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);
countDownLatch.await();
}
创建临时节点
//创建临时node 当服务挂的之后会自动吧node给删除 避免了服务宕机之后出现还能请求服务的情况
public Boolean createNodeForTemporary(String path, String data) throws KeeperException, InterruptedException{
path = this.pathChange(path);
if(!this.nodeExists(path)) {
String listPath[] = path.split("/");
String prePath = "";
for(int i=1; i<listPath.length-1; i++){
prePath = prePath + "/" + listPath[i];
if(!this.nodeExists(prePath)){
//CreateMode.EPHEMERAL 创建临时节点
this.zookeeper.create(prePath, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}
}
this.zookeeper.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
return true;
}else{
return false;
}
}
创建临时
//创建node
public Boolean createNode(String path, String data) throws KeeperException, InterruptedException{
path = this.pathChange(path);
if(!this.nodeExists(path)) {
String listPath[] = path.split("/");
String prePath = "";
for(int i=1; i<listPath.length-1; i++){
prePath = prePath + "/" + listPath[i];
if(!this.nodeExists(prePath)){
this.zookeeper.create(prePath, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
this.zookeeper.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
return true;
}else{
return false;
}
}
获取子节点
//获取子节点
public List<String> getChilds(String path) throws KeeperException, InterruptedException{
path = this.pathChange(path);
if(this.nodeExists(path)){
return this.zookeeper.getChildren(path, false);
}else{
return null;
}
}
删除节点
//由于zk节点下有子节点是不能直接删除的
public void rmr(String path) throws Exception {
//获取路径下的节点
path = this.pathChange(path);
List<String> children = this.zookeeper.getChildren(path, false);
for (String pathCd : children) {
//获取父节点下面的子节点路径
String newPath = "";
//递归调用,判断是否是根节点
if (path.equals("/")) {
newPath = "/" + pathCd;
} else {
newPath = path + "/" + pathCd;
}
rmr(newPath);
}
//删除节点,并过滤zookeeper节点和 /节点
if (path != null && !path.trim().startsWith("/zookeeper") && !path.trim().equals("/")) {
this.zookeeper.delete(path, -1);
//打印删除的节点路径
System.out.println("被删除的节点为:" + path);
}
}
ZooKeeper的使用
第一步标识将要被注册的服务
//将服务用 @RPCServer 用来表示该服务将被注册
@Service
@RPCServer
public class serverWorld2 {
public String message(String world){
return "Hello world";
}
}
第二步将建立连接 将服务createnode
代码比较多 剪切其中一块
//连接zk
ZookeeperBase zk = new ZookeeperBase(ZookeeperIpHost);
//创建节点 获取当前项目路径
Enumeration<URL> urls =Thread.currentThread().getContextClassLoader().getResources(baseackage.replace(".", "/"));
while (urls.hasMoreElements()){
URL url = urls.nextElement();
if(null != url){
String protocol = url.getProtocol();
if(protocol.equals("file")){
String packagePath = url.getPath().replaceAll("%20"," ");//去空格
System.out.println("server"+packagePath);
File file = new File(packagePath);
//遍历目录将服务放入map中
func(file,baseackage);
}
}
}
if(!zk.nodeExists("/RPCSERVER")){
zk.createNode("/RPCSERVER", "ROOT");
}
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
if(!zk.nodeExists("/RPCSERVER/"+entry.getKey())){
zk.createNode("/RPCSERVER/"+entry.getKey(), entry.getValue());
}
InetAddress address = InetAddress.getLocalHost();//获取的是本地的IP地址 //PC-20140317PXKX/192.168.0.121
String hostAddress = address.getHostAddress();//192.168.0.121
if(!zk.nodeExists("/RPCSERVER/"+entry.getKey()+"/"+hostAddress+":"+rpc.getPort())){
//使用临时节点当zk断开连接的时候会自动消失
zk.createNodeForTemporary("/RPCSERVER/"+entry.getKey()+"/"+hostAddress+":"+rpc.getPort(),hostAddress+":"+rpc.getPort());
System.out.println("/RPCSERVER/"+entry.getKey()+"/"+hostAddress+":"+rpc.getPort()+" 创建");
}
}
第三步配置信息
<bean id="zkServer" class="main.java.zkServer.ZkServer" init-method="start" >
<property name="ZookeeperIpHost" value="172.16.12.34:2181"></property>
<!-- 服务注册扫描包 -->
<property name="baseackage" value="main.java.work.service"></property>
</bean>
ZooKeeper java 大致流程
1.将服务标识
2.读取配置文件的ip:host 将zookeeper建立连接
3.读取配置文件扫描的包 将这些包下的服务信息在zookeeper中建立
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15344.html