MyRPCDemo netty+jdk动态代理+反射+序列化,反序列化手写rpc框架

RPC

RPC(remote procedure call)远程过程调用
RPC是为了在分布式应用中,两台主机的Java进程进行通信,当A主机调用B主机的方法时,过程简洁,就像是调用自己进程里的方法一样。
RPC框架的职责就是,封装好底层调用的细节,客户端只要调用方法,就能够获取服务提供者的响应,方便开发者编写代码。
RPC底层使用的是TCP协议,服务端和客户端和点对点通信。

RPC与http

以我写的rpcdemo为例,我在rpcserver端LogonService写了一个checkLogon方法,我想在rpcclient端中直接调用rpcserver端的checkLogon方法。
怎么办?如果是web项目的话本身在tomcat启动了,可以发布一个servlet(http接口,或webservice)接口交互。http接口或webservi都是基于http的,
性能也没rpc高,目前服务器配置等都上来了,springcloud rpc也是基于http协议实现的。
比如主流的dubbo rpc框架,是使用netty启动了一个单独端口的服务,zookeeper作为注册中心,客户端启动后通过nettyclient连接上来,通过netty通信调用
服务器的方法,通过socket传输,,直接走的tcp/ip协议,比http性能更高。

手写rpc框架

技术路线:netty+动态代理+反射+序列化+反序列化

实现原理:

  1. rpc服务端使用netty发布一个tcp/ip socket服务
  2. rpc客户端使用连接上netty服务端,建立与服务端的连接
  3. 客户端通过动态代理生成接口代理类,把要调用的类名,方法,参数类型,参数等序列化后发送到netty服务端
  4. 服务端收到请求解析类名,方法,参数类型,参数等反序列化后通过反射机制调用该方法,在把响应序列化后返回到客户端
  5. 客户端收到响应后反序列化得到调用结果

主要涉及以下类

学习使用,客户端,服务器有重复代码,项目上使用的话可以封装成一个maven模块,项目中通过pom引入该rpc模块即可

公共

  1. RpcRequest,RpcResponse 创建netty服务器数据 数据输入 输出对象
  2. ByteUtils JsonSerialization 序列化与反序列化工具类 方便对象在netty管道传输
  3. NettyProtocolHandler netty客户端,服务器通信处理 (客户端发送请求给服务器端,服务端处理完返回数据给客户端)

客户端
4. ClientNetty 连接netty服务端
5. ClientHandler 处理服务器返回的响应
6. ProxyFactory 动态代理工厂,用于生成LogonService接口的动态代理类。
7. RPCInvocationHandler 通过代理对象的invoke方法 把class,method,参数等信息序列化后通过netty客户端发送给netty服务器端处理
8. LogonService接口,和服务端结构一样的LogonService接口,rpc使用的动态代理技术,要求消费者和提供者都必须定义一样的接口类
9. ClientMain 客户端项目启动入口main方法启动

服务端
10. ServerNetty 开启netty服务
11. ServerHandler 处理客户端请求,解析参数得到class,method从concurrentHashMap获取实例后通过反射机制调用方法
12. LogonService接口,和客户端结构一样的LogonService接口,rpc使用的动态代理技术,要求消费者和提供者都必须定义一样的接口类
13. LogonServiceImpl 实现类,因为是服务提供者,需要实现LogonService接口,供服务消费者调用
14. ServerMain 服务端项目启动入口main方法启动

RPCClient项目目录树

在这里插入图片描述

RPCServer项目目录树

在这里插入图片描述

客户端,服务端pom依赖

客户端,服务端都为普通的maven 工程,只引入了netty和jackson依赖

 <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.0</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport</artifactId>
            <version>4.1.75.Final</version>
        </dependency>
    </dependencies>

公共类

RpcRequest,RpcResponse
package com.wying.rpc;

import java.util.Arrays;

/**
 * description:RpcRequest
 * date: 2022/5/3
 * author: gaom
 * version: 1.0
 */
public class RpcRequest {
   
    private String className;

    private String  methodName;

    private Class[] paramType;

    private Object[] args;

    public String getClassName() {
   
        return className;
    }

    public void setClassName(String className) {
   
        this.className = className;
    }

    public String getMethodName() {
   
        return methodName;
    }

    public void setMethodName(String methodName) {
   
        this.methodName = methodName;
    }

    public Class[] getParamType() {
   
        return paramType;
    }

    public void setParamType(Class[] paramType) {
   
        this.paramType = paramType;
    }

    public Object[] getArgs() {
   
        return args;
    }

    public void setArgs(Object[] args) {
   
        this.args = args;
    }

    @Override
    public String toString() {
   
        return "RpcRequest{" +
                "className='" + className + '\'' +
                ", methodName='" + methodName + '\'' +
                ", paramType=" + Arrays.toString(paramType) +
                ", args=" + Arrays.toString(args) +
                '}';
    }
}

package com.wying.rpc;

/**
 * description:RpcResponse
 * date: 2022/5/3
 * author: gaom
 * version: 1.0
 */
public class RpcResponse {
   
    private int code;

    private Object result;

    public int getCode() {
   
        return code;
    }

    public void setCode(int code) {
   
        this.code = code;
    }

    public Object getResult() {
   
        return result;
    }

    public void setResult(Object result) {
   
        this.result = result;
    }

    @Override
    public String toString() {
   
        return "RpcResponse{" +
                "code=" + code +
                ", result=" + result +
                '}';
    }
}

ByteUtils,JsonSerialization
package com.wying.rpc;

import java.nio.ByteBuffer;

/**
 * description:ByteUtils
 * date: 2022/5/3
 * author: gaom
 * version: 1.0
 */
public class ByteUtils {
   
   
    public static byte[] short2bytes(short v) {
   
        byte[] b = new byte[4];
        b[1] = (byte) v;
        b[0] = (byte) (v >>> 8);
        return b;
    }

  
    public static byte[] int2bytes(int v) {
   
        byte[] b = new byte[4];
        b[3] = (byte) v;
        b[2] = (byte) (v >>> 8);
        b[1] = (byte) (v >>> 16);
        b[0] = (byte) (v >>> 24);
        return b;
    }

    
    public static byte[] long2bytes(long v) {
   
        byte[] b = new byte[8];
        b[7] = (byte) v;
        b[6] = (byte)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值