Zookeeper(3)实战

RMI

RMI(Remote Method Invocation) 远程方法调用。
RMI 是从 JDK1.2 推出的功能,它可以实现在一个 Java 应用中可以像调用本地方法一样调用另一个服务器中 Java 应用(JVM)中的内容。
RMI 是 Java 语言的远程调用,无法实现跨语言。

执行流程

Zookeeper(3)实战
Registry(注册表)是放置所有服务器对象的命名空间。 每次服务端创建一个对象时,它都会使用 bind()或 rebind()方法注册该对象。 这些是使用称为绑定名称的唯一名称注册的。
要调用远程对象,客户端需要该对象的引用。即通过服务端绑定的名称从注册表中获取对象(lookup()方法)。

API介绍

Remote 接口
java.rmi.Remote 定义了此接口为远程调用接口。如果接口被外部调用,需要继承此接口。

RemoteException 类
java.rmi.RemoteException继承了 Remote 接口的接口,如果方法是允许被远程调用的,需要抛出此异常。

UnicastRemoteObject 类
java.rmi.server.UnicastRemoteObject此类实现了 Remote 接口和 Serializable 接口。自定义接口实现类除了实现自定义接口还需要继承此类。

LocateRegistry 类
java.rmi.registry.LocateRegistry可以通过 LocateRegistry 在本机上创建Registry,通过特定的端口就可以访问这个Registry

Naming 类
java.rmi.NamingNaming 定义了发布内容可访问 RMI 名称。也是通过Naming 获取到指定的远程方法。(bind lookup都在此下)

server端
package com.wyt;

import com.wyt.service.DemoService;
import com.wyt.service.Impl.DemoServiceImpl;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

public class demoServer {
    public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
        //将对象实例化
        DemoService demoService=new DemoServiceImpl() ;
        //创建本地注册表
        LocateRegistry.createRegistry(8888);
        //对象绑定到注册表中  8888/加唯一标识
        Naming.bind("rmi://localhost:8888/demoService",demoService);

    }
}

客户端
import com.wyt.service.DemoService;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class ClientDemo {
    public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
        DemoService demoService=(DemoService) Naming.lookup("rmi://localhost:8888/demoService");
        String result=demoService.demo("wangyuntong");
        System.out.println(result);
    }
}

使用zookeeper

package com.wyt;

import com.wyt.service.UsersService;
import com.wyt.service.impl.UsersServiceImpl;
import org.apache.zookeeper.*;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

public class ServerDemo implements Watcher {
    public static void main(String[] args) throws IOException, AlreadyBoundException, KeeperException, InterruptedException {
        UsersService usersService=new UsersServiceImpl();
        LocateRegistry.createRegistry(8888);
        String url="rmi://localhost:8888/user";
        Naming.bind(url,usersService);
        //将url放到zookeeper的节点中
        ZooKeeper zooKeeper=new ZooKeeper("192.168.217.131:2181," +
                "192.168.217.131:2182," +
                "192.168.217.131:2183",150000,new ServerDemo());

        zooKeeper.create("/wyt/service",url.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT_SEQUENTIAL);

        System.out.println("服务发布成功");
    }


    @Override
    public void process(WatchedEvent watchedEvent) {
        if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
            System.out.println("chenggong");
        }
    }
}

package com.wyt;

import com.wyt.service.UsersService;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.rmi.Naming;
import java.rmi.NotBoundException;

class ClientDemo implements Watcher {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException, NotBoundException {
        ZooKeeper zooKeeper=new ZooKeeper("192.168.217.131:2181," +
                "192.168.217.131:2182," +
                "192.168.217.131:2183",150000,new ClientDemo());
        byte[] bytes=zooKeeper.getData("/wyt/service0000000001",new ClientDemo(),null);
        String url=new String(bytes);
        System.out.println(url);
        UsersService userService=(UsersService)Naming.lookup(url);
        String re=userService.findUsers("王韵通");
        System.out.println(re);
    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
            System.out.println("chenggong");
        }
    }
}

切记:UsersService两个类名必须一致(服务端和客户端)

上一篇:一次完整的渗透测试&仅供学习研究


下一篇:log4j2安全漏洞