Zookeeper (三)Zookeeper 实战(RMI)(包含案例源码及解析)

tech2022-12-10  107

案例源码gitee地址:https://gitee.com/BanSheng/zookeeper-demo/tree/master/rmidemo

 Zookeeper 实战

实战案例介绍:使用 Zookeeper 与 RMI 技术实现一个 RPC 框架。

RPC:RPC(Remote Procedure Call)远程过程调用。

1 基于 RMI 实现远程方法调用

1.1RMI 简 介

RMI(Remote Method Invocation) 远程方法调用。

RMI 是从 JDK1.2 推出的功能,它可以实现在一个 Java 应用中可以像调用本地方法一样

调用另一个服务器中 Java 应用(JVM)中的内容。

RMI 是 Java 语言的远程调用,无法实现跨语言。

1.2执行流程

Registry(注册表)是放置所有服务器对象的命名空间。 每次服务端创建一个对象时,它都会使用 bind()或 rebind()方法注册该对象。 这些是使用称为绑定名称的唯一名称注册的。

要调用远程对象,客户端需要该对象的引用。即通过服务端绑定的名称从注册表中获取对象(lookup()方法)。

1.3RMI 的 API 介绍

1.3.1 Remote 接口

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

1.3.2 RemoteException 类

java.rmi.RemoteException

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

1.3.3 UnicastRemoteObject 类

java.rmi.server.UnicastRemoteObject

此类实现了 Remote 接口和 Serializable 接口。

自定义接口实现类除了实现自定义接口还需要继承此类。

1.3.4 LocateRegistry 类

java.rmi.registry.LocateRegistry

可以通过 LocateRegistry 在本机上创建 Registry,通过特定的端口就可以访问这个Registry。

1.3.5 Naming 类

java.rmi.Naming

Naming 定义了发布内容可访问 RMI 名称。也是通过 Naming 获取到指定的远程方法。

1.4创建 Server 端

1.4.1 创建项目

1.4.2 创建接口

/** * 定义允许远程调用接口,该接口必须要实现 Remote 接口 * 允许被远程调用的方法必须要抛出 RemoteException */ public interface DemoService extends Remote { String demo(String str) throws RemoteException; }

1.4.3 创建接口实现类

/** * 接口实现类必须要继承 UnicastRemoteObject 。 * 会自动添加构造方法,需要修改为 public */ public class DemoServiceImpl extends UnicastRemoteObject implements DemoService { public DemoServiceImpl() throws RemoteException { } @Override public String demo(String str) throws RemoteException { return "Hello RMI "+str; } }

1.4.4 编写主方法

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

1.5创建 Client 端

1.5.1 创建项目

1.5.2 复制服务端接口

/** * 定义允许远程调用接口,该接口必须要实现 Remote 接口 * 允许被远程调用的方法必须要抛出 RemoteException */ public interface DemoService extends Remote { String demo(String str) throws RemoteException; }

1.5.3 创建主方法

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("bjsxt"); System.out.println(result); } }

2 使用 Zookeeper 作为注册中心实现 RPC

 

2.1创建服务端

2.1.1 创建项目

2.1.2 修改 POM 文件添加依赖

<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.6.0</version> </dependency>

2.1.3 创建接口

public interface UsersService extends Remote { String findUsers(String str) throws RemoteException; }

2.1.4 创建接口实现类

public interface UsersService extends Remote { String findUsers(String str) throws RemoteException; } public class UsersServiceImpl extends UnicastRemoteObject implements UsersService { public UsersServiceImpl() throws RemoteException { } @Override public String findUsers(String str) throws RemoteException { return "Hello Zookeeper "+str; } }

2.1.5 编写主方法

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.233.130:2181,192.168.233.130:2182,192.168.233. 130:2183",150000,new ServerDemo()); // 创建 Znode zooKeeper.create("/bjsxt/service",url.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println("服务发布成功"); } }

2.2创建客户端

2.2.1 创建项目

2.2.2 修改 POM 文件添加依赖

<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.6.0</version> </dependency>

2.2.3 创建接口

public interface UsersService { String findUsers(String str); }

2.2.4 编写主方法

public class ClientDemo implements Watcher { public static void main(String[] args) throws IOException, KeeperException, InterruptedException, NotBoundException { ZooKeeper zooKeeper = new ZooKeeper("192.168.233.130:2181,192.168.233.130:2182,192.168.233.130:2183",150000,new ClientDemo()); byte[] bytes = zooKeeper.getData("/bjsxt/service",new ClientDemo(),null); String url = new String(bytes); UsersService usersService = (UsersService) Naming.lookup(url); String result = usersService.findUsers("Bjsxt"); System.out.println(result); } @Override public void process(WatchedEvent event) { if(event.getState() == Event.KeeperState.SyncConnected){ System.out.println("连接成功"); } } }

案例源码gitee地址:https://gitee.com/BanSheng/zookeeper-demo/tree/master/rmidemo

最新回复(0)