美文网首页
RPC-准备阶段

RPC-准备阶段

作者: 白璞1024 | 来源:发表于2020-02-16 10:02 被阅读0次

    他是一种通过网络从远程计算机程序上请求服务,不需要了解底层网络的技术

    完整的RPC网络调用流程

    1. 服务消费方:以本地调用方式调用客户端存根;
    2. 什么叫客户端存根?就是远程方法在本地的模拟对象,一样的也有方法名,也有方法参数,client stub 接收到调用后负责将方法名方法的参数等包装,并将包装后的信息通过网络发送到服务端。
    3. 服务端收到消息后,交给代理存根在服务器的部分后尽心解码为实际的方法名和参数
    4. server stub 根据解码结果调用服务器上本地的实际服务。
    5. 本地服务执行,将结果返回给server stub
    6. server stub将返回的结果打包成消息并发送给消费方
    7. client stub接受到消息进行解码
    8. 消费方得到最后的结果。

    写一个类似框架,需要解决几个不常用的问题

    1. 代理模式
    2. 序列化问题 利用java的相关机制,也就是Serializable
    3. 通信问题 BIO
    4. 登记的服务实力化问题 使用反射机制
      • 在运行时候,判断任意一个对象所属的类
      • 运行时候构造人意一个类的对象
      • 运行时候,判断任意一个类所就有的方法和成员变量
      • 运行时候,调用任意一个对象的方法
      • 生成动态代理
        下边的代码简单的解释一下上述的问题

    1、 代理模式

    //静态代理方法的实现
    /**
     * 接口类
     */
    public interface IGetServer {
        void choice(String desc);
    }
    
     /**
     * 接口的实现类
     */
    public class Receptionist implements IGetServer {
        public void choice(String desc) {
            System.out.println(desc);
        }
    }
    /**
    *代理类
    */
    public class ProxyServer  implements InvocationHandler {
        private  Object receptionist;//实现类的实例
        public ProxyServer(Object receptionist) {
            this.receptionist = receptionist;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("执行对应的方法之前执行的方法");
            //实际的方法
            Object result = method.invoke(receptionist,args);
            System.out.println("执行之后执行的方法");
            return result;
        }
    }
    
    
    //-----------------------------------
    /**
    *调用类
    */
    
    public class Proxyclient {
        //调用代理方法
        public static void main(String[] args) {
            IGetServer ig = (IGetServer) Proxy.newProxyInstance(IGetServer.class.getClassLoader(),new Class[]{IGetServer.class},new ProxyServer(new Receptionist()));
            ig.choice("这里是我要传入的参数");
        }
    
    }
    

    2、 序列化

    bean同时实现了Se rierizable就好了

    
    public class SerialBean implements Serializable {
        private final String name;
        private  final  String age;
    
        public SerialBean(String name, String age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public String getAge() {
            return age;
        }
    }
    

    主要用到的是如何调用序列化和反序列化

    
    public class TestSerial {
        public static void main(String[] args) {
            setSer();//序列化
            getSer();
        }
    
    
        //序列化
        private static void setSer()  {
            SerialBean bean = new SerialBean("Mark","123");
            List<String> list= new ArrayList<String>();
            list.add("my name");
            list.add( "is " );
            list.add("mark");
    
            ObjectOutputStream os = null;
            try {
                os = new ObjectOutputStream(new FileOutputStream("/Users/weblogic/study/Serial.txt"));
                os.writeObject(bean);
                os.writeObject(list);
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        public static void getSer(){
            try {
                ObjectInputStream is = new ObjectInputStream(
                        new FileInputStream("/Users/weblogic/study/Serial.txt"));
                SerialBean bean = (SerialBean) is.readObject();
                System.out.println(bean.getAge());
                System.out.println(bean.getName());
                List tempList  = (List) is.readObject();
                for(Iterator iterable = tempList.iterator();iterable.hasNext();){
                    System.out.println(iterable.next());
                }
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    

    3、 反射

    
    public class RefleDemo  {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            //实例化对象的标准用法
            Servant servant = new Servant();
            servant.service("hello|");
          //  全限定名拿到勒的class对象
            Class servantClazz = Class.forName("cn.baip.netty.rpc.refle.Servant");
            //通过class对象拿到类的实例
            Servant servant1 = (Servant) servantClass.newInstance();
    
            //拿到所有的方法名
            Method[] methods = servantClazz.getMethods();
            for (Method method :methods){
                System.out.println(method.getName());//方法的名称
                if(method.getName().equals("toString")){
                    try {
                        System.out.println(method.invoke(servant1,null));
                        System.out.println("执行,"+method.invoke(servantClazz.newInstance(),null));
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    

    相关文章

      网友评论

          本文标题:RPC-准备阶段

          本文链接:https://www.haomeiwen.com/subject/ehoyfhtx.html