zoukankan      html  css  js  c++  java
  • RPC和RestFul

    什么是REST

    REST是一种架构风格,指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
    REST规范把所有内容都视为资源,网络上一切皆资源。 REST并没有创造新的技术,组件或服务,只是使用Web的现有特征和能力。
    可以完全通过HTTP协议实现,使用 HTTP 协议处理数据通信。
    REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。

    什么是RPC

    远程方法调用,就是像调用本地方法一样调用远程方法.
    RPC框架要做到的最基本的三件事:
    
    1、服务端如何确定客户端要调用的函数;
    在远程调用中,客户端和服务端分别维护一个【ID->函数】的对应表, ID在所有进程中都是唯一确定的。
    客户端在做远程过程调用时,附上这个ID,服务端通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。
    2、如何进行序列化和反序列化; 客户端和服务端交互时将参数或结果转化为字节流在网络中传输,那么数据转化为字节流的或者将字节流转换成能读取
    的固定格式时就需要进行序列化和反序列化,序列化和反序列化的速度也会影响远程调用的效率。
    3、如何进行网络传输(选择何种网络协议); 多数RPC框架选择TCP作为传输协议,也有部分选择HTTP。如gRPC使用HTTP2。不同的协议各有利弊。TCP更加高效,
    而HTTP在实际应用中更加的灵活。

    RPC简单案例实现

    创建client

    package com.hadoop.hdfs.rpc2.client;
    
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.Proxy;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Client<T> {
        public T getClass(Class<?> clazz, InetSocketAddress address) {
            T t = (T) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
                    new Class<?>[]{clazz.getInterfaces()[0]}, (proxy, method, args) -> {
                        Socket socket = new Socket();
                        socket.connect(address);
                        try (
                                ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                        ) {
                            objectOutputStream.writeUTF(clazz.getName());
                            objectOutputStream.writeUTF(method.getName());
                            objectOutputStream.writeObject(method.getParameterTypes());
                            objectOutputStream.writeObject(args);
    
                            return objectInputStream.readObject();
                        }finally {
                            if (socket!=null){
                                socket.close();
                            }
                        }
                    });
    
            return t;
        }
    }

    创建server

    package com.hadoop.hdfs.rpc2.server;
    
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.Method;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    
    public class Server {
        //线程池
        static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    
        public static void exporter(String host, int port) throws IOException {
            try (ServerSocket serverSocket = new ServerSocket();) {
                serverSocket.bind(new InetSocketAddress(host, port));
                //不断监听
                while (true) {
                    executor.execute(new Task(serverSocket.accept()));
                }
            }
        }
    
        private static class Task implements Runnable {
            Socket client = null;
    
            public Task(Socket client) {
                this.client = client;
            }
    
            @Override
            public void run() {
                try (
                        ObjectInputStream objectInputStream = new ObjectInputStream(client.getInputStream());
                        ObjectOutputStream objectOutputStream = new ObjectOutputStream(client.getOutputStream());
                ) {
                    String interfaceName = objectInputStream.readUTF();
                    Class servce = Class.forName(interfaceName);
    
                    String methodName = objectInputStream.readUTF();
    
                    Class<?>[] parameterTypes = (Class<?>[]) objectInputStream.readObject();
    
                    Object[] arguments = (Object[]) objectInputStream.readObject();
    
                    Method method = servce.getMethod(methodName, parameterTypes);
    
                    Object obj = method.invoke(servce.newInstance(), arguments);
    
                    objectOutputStream.writeObject(obj);
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    创建调用的接口和实现类

    package com.hadoop.hdfs.rpc2.server;
    
    public interface Method {
        public void method1();
    }
    package com.hadoop.hdfs.rpc2.server;
    
    public class MethodImpl implements Method {
        @Override
        public void method1() {
            System.out.println("method1");
        }
    }

    创建测试类

    package com.hadoop.hdfs.rpc2.client;
    
    import com.hadoop.hdfs.rpc2.server.Method;
    import com.hadoop.hdfs.rpc2.server.MethodImpl;
    import com.hadoop.hdfs.rpc2.server.Server;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    
    public class Test {
        public static void main(String[] args) {
            //服务器
            new Thread(() -> {
                try {
                    Server.exporter("localhost",8088);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
            //客户端
            new Thread(() -> {
                Client<Method> import1 = new Client();
                Method method = import1.getClass(MethodImpl.class,new InetSocketAddress("localhost",8088));
                method.method1();
            }).start();
        }
    }
    我凝视这恒星,等待这那场风暴,我已经准备好了
  • 相关阅读:
    Delphi 与 VC 共享接口和对象
    Delphi线程类 DIY(把类指针作为参数传进去,就可以执行类里面的方法啦)
    delphi 在多线程中使用 CreateOleObject 导致失败(一定要使用CoInitialize和CoUninitialize,举例查询WMI)
    delphi调用LUA函数来处理一些逻辑
    后台管理系统
    .NET平台机器学习
    kafka
    一些技术视频资源
    异步
    CQRS(命令查询职责分离)和 EDA(事件驱动架构)
  • 原文地址:https://www.cnblogs.com/cheng5350/p/11749004.html
Copyright © 2011-2022 走看看