RPC 手写实现客户端调用服务端类里面的method Netty

一。什么是RPC

RPC(Remote Procedure Call Protocol)远程过程调用协议
RPC是协议:既然是协议就只是一套规范,那么就需要有人遵循这套规范来进行实现。
目前典型的RPC实现包括:Dubbo、Thrift、GRPC、Hetty等

二。RPC由四部分组成

RPC和Netty的关系

通信模型(网络通信框架)
服务定位:使用给定的通信方式,与确定IP与端口及方法名称确定具体的过程或方法
远程代理对象
序列化协议

其中2.3两项可以概括为“调用控制协议”
Netty只是网络通信框架,目的是让你用最少的代码构建出足够支撑网络通信的功能,它是基于JAVA的NIO进行封装后的产品。

三。手写实现千万架构必备RPC框架及原理分析

(客户端调用服务端类里面的method)

思路(步骤):
1.客户端和服务端通信
2.客户端通过outputstream传递 包名 + 类名 + 方法名 + 方法参数
3.服务端通过Inputstream接收 包名 + 类名 + 方法名 + 方法参数,利用反射技术执行

1。两个进程通信

服务端(提供ip+端口让别人连接)
public static void publishServer() throws  Exception {
    ServerSocket serverSocket = new ServerSocket(6666);
    while (true) {
        serverSocket.accept();
    }
}

客户端
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",6666);
    }
}

2.客户端传递信息

public static void main(String[] args) throws IOException {
    //1。连接服务端
    Socket socket = new Socket("127.0.0.1",6666);
    
    //2.封装要传递的信息 包名 类名 方法名 参数名称
    RpcInfo rpcInfo = new RpcInfo();
    rpcInfo.setPackageName("com.test.web.dao");
    rpcInfo.setClazzName("OrderDao");
    rpcInfo.setMethodName("server");
    Object[] params = new Object[]{"华安"};
    rpcInfo.setArgs(params);
    
    //3传递 objectOutputStream.writeObject(rpcInfo);
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
    objectOutputStream.writeObject(rpcInfo);
    objectOutputStream.flush();
    objectOutputStream.close();
}

3.服务端接收信息并利用反射技术执行方法

public class Server {
    public static void main(String[] args) throws Exception {
        publishServer();
    }

    /*创建服务端并接受连接请求*/
    public static void publishServer() throws  Exception {
        ServerSocket serverSocket = new ServerSocket(6666);
        ExecutorService executorService = Executors.newFixedThreadPool(5);  //并发编程执行器
        while (true) {
            System.out.println("服务端等待连接......");
            Socket accept = serverSocket.accept();
            System.out.println("服务端连接成功......");
            executorService.execute(new ServerHandler(accept));  //并发编程执行器 执行线程
        }
    }
}
public class ServerHandler implements Runnable {
    private Socket socket;

    public ServerHandler(Socket socket) {
        this.socket = socket;
    }

    /*调用 OrderDao.serve*/
    @Override
    public void run()  {
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            RpcInfo rpcInfo = (RpcInfo) objectInputStream.readObject();
            Class<?> clazz = Class.forName(rpcInfo.getPackageName() + "." + rpcInfo.getClazzName());  //利用反射创建类:UserDao
            Class[] classes = new Class[rpcInfo.getArgs().length];  //classes是serve这个方法所有的参数类型(从客户端传过来)
            for (int i = 0 ;i<classes.length;i++){
                classes[i] = rpcInfo.getArgs()[i].getClass();
            }
            Method method = clazz.getMethod(rpcInfo.getMethodName(), classes);
            method.invoke(clazz.newInstance(),rpcInfo.getArgs());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四。服务暴露问题的优化(相当于做一个eureka)

将服务端的类和方法选择性地展示在页面上给客户端调用

思路:
1.确定包下的业务类
2.解析类是否需要被发布
3.解析方法是否需要被发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘然生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值