• JDK原生RMI结合zookeeper使用


    RMIAPI

    1. Remote 接口
      java.rmi.Remote
      定义了此接口为远程调用接口。如果接口被外部调用,需要继承此接口。
    2. RemoteException 类
      java.rmi.RemoteException
      继承了 Remote 接口的接口,如果方法是允许被远程调用的,需要抛出此异常。
    3. UnicastRemoteObject 类
      java.rmi.server.UnicastRemoteObject
      此类实现了 Remote 接口和 Serializable 接口。
      自定义接口实现类除了实现自定义接口还需要继承此类
    4. LocateRegistry 类
      java.rmi.registry.LocateRegistry
      可以通过 LocateRegistry 在本机上创建 Registry,通过特定的端口就可以访问这个Registry。
    5. Naming 类
      java.rmi.Naming
      Naming 定义了发布内容可访问 RMI 名称。也是通过 Naming 获取到指定的远程方法。

    RMI基本使用

    服务端

    创建工程

    创建服务提供方接口

    package com.xzlf.service;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    // 服务提供方必须继承Remote接口
    public interface DemoService extends Remote {
        String demo(String str) throws RemoteException;
    }
    
    

    创建服务提供方接口实现

    package com.xzlf.service;
    
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    public class DemoServiceImpl extends UnicastRemoteObject implements DemoService {
    
        public DemoServiceImpl() throws RemoteException {
        }
    
        @Override
        public String demo(String str) throws RemoteException {
            return "Hello RMI " + str;
        }
    }
    
    

    把接口注册到注册表中供远程调用

    package com.xzlf.service;
    
    import java.net.MalformedURLException;
    import java.rmi.AlreadyBoundException;
    import java.rmi.Naming;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    
    public class RMIApp {
        public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
            DemoService demoService = new DemoServiceImpl();
            // 创建本地注册表
            LocateRegistry.createRegistry(8888);
            // 将对象绑定到注册表中
            Naming.bind("rmi://localhost:8888/demo", demoService);
        }
    }
    
    

    消费方

    提供接口引用

    package com.xzlf.service;
    
    // 服务消费放不用继承Remote接口
    public interface DemoService /*extends Remote */{
        String demo(String str) /*throws RemoteException*/;
    }
    
    

    直接通过Naming.lookup静态方法获取远程对象

    package com.xzlf.service;
    
    import java.net.MalformedURLException;
    import java.rmi.Naming;
    import java.rmi.NotBoundException;
    import java.rmi.RemoteException;
    
    public class Client {
        public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
            DemoService demoService = (DemoService) Naming.lookup("rmi://localhost:8888/demo");
            String result = demoService.demo("张三");
            System.out.println(result);
        }
    }
    
    

    测试

    RMI+zookeeper使用

    服务端

    创建工程,导入依赖

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

    创建服务提供方接口

    package com.xzlf.service;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface UserService extends Remote {
    
        String getUserInfo(String name) throws RemoteException;
    }
    

    创建服务提供方接口实现

    package com.xzlf.service.impl;
    
    import com.xzlf.service.UserService;
    
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    public class UserSeriveImpl extends UnicastRemoteObject implements UserService {
    
        // 注意修改构造方法为 public
        public UserSeriveImpl() throws RemoteException {
            super();
        }
    
        @Override
        public String getUserInfo(String name) throws RemoteException {
            return "zookeeper demo " + name;
        }
    }
    
    

    把接口注册到注册表中并把地址添加到zookeeper注册中心供消费方获取

    package com.xzlf.service.app;
    
    import com.xzlf.service.UserService;
    import com.xzlf.service.impl.UserSeriveImpl;
    import org.apache.zookeeper.*;
    
    import java.io.IOException;
    import java.rmi.AlreadyBoundException;
    import java.rmi.Naming;
    import java.rmi.registry.LocateRegistry;
    
    public class Demo implements Watcher {
    
        public static void main(String[] args) throws IOException, AlreadyBoundException, KeeperException, InterruptedException {
            UserService userService = new UserSeriveImpl();
            LocateRegistry.createRegistry(9999);
            String url  = "rmi://localhost:9999/user";
            Naming.bind(url, userService);
    
            //将 url 信息放到 zookeeper 的节点中
            ZooKeeper zooKeeper = new ZooKeeper("redis-server:2181", 15000, new Demo());
    
            String path = zooKeeper.create("/service/user", url.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("服务发布成功");
    
        }
    
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == Event.KeeperState.SyncConnected){
                System.out.println("连接成功");
            }
        }
    }
    
    

    消费方

    提供接口引用

    package com.xzlf.service;
    
    public interface UserService {
        String getUserInfo(String name);
    }
    
    

    先从zookeeper注册中心获取远程地址,然后通过Naming调用

    package com.xzlf.controller;
    
    import com.xzlf.service.UserService;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.data.Stat;
    
    import java.io.IOException;
    import java.rmi.Naming;
    import java.rmi.NotBoundException;
    
    public class UserController implements Watcher {
        public static void main(String[] args) throws IOException, NotBoundException, KeeperException, InterruptedException {
            ZooKeeper zooKeeper = new ZooKeeper("redis-server:2181", 15000, new UserController());
            byte[] data = zooKeeper.getData("/service/user", new UserController(), new Stat());
            // 从zookeeper 获取远程调用url
            UserService userService = (UserService) Naming.lookup(new String(data));
            String userInfo = userService.getUserInfo("张三");
            System.out.println(userInfo);
        }
    
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == Event.KeeperState.SyncConnected){
                System.out.println("连接成功");
            }
        }
    }
    
    

    测试

    zookeper

    控制台输出

    重视基础,才能走的更远。
  • 相关阅读:
    第1章 基础知识
    图学习学术速递[2021/10/14]
    图学习学术速递[2021/10/15]
    期望—方差—协方差—协方差矩阵—相关系数
    哈达玛积
    论文解读(MPNN)Neural Message Passing for Quantum Chemistry
    pip 命令总结
    图学习学术速递[2021/10/13]
    Codeforces Round #693 (Div. 3) D. Even-Odd Game
    Codeforces Round #693 (Div. 3) B. Fair Division
  • 原文地址:https://www.cnblogs.com/xzlf/p/14275271.html
Copyright © 2020-2023  润新知