/lf-mk-java-custom-rpc

自己动手实现rpc框架:https://www.imooc.com/learn/1158

Primary LanguageJavaMIT LicenseMIT

customRPC

自己动手实现rpc框架:https://www.imooc.com/learn/1158

1.大纲:

·理论:rpc核心原理,技术介绍
·实战:gk-rpc代码实现,案例
·总结:

2.理论:

1.概念:
    RPC:Remote Procedure Call,即远程过程调用
        分布式常见的通讯方式,从跨进程到跨物理机已有几十年历史
    跨进程交互形式:
        RESTFUL
        WEBSERVICE
        HTTP
        基于DB做数据交换
        基于MQ做数据交换
2.交互形式对比:
    1.依赖中间件做数据交互:异步
        系统A -> 数据存储(DB,MQ,redis) -> 系统B
        常用:mysql,rabbitmq,kafka,redis,可用性要求较高的时候,常用mysql,rabbitmq做存储中间件,任务存储没任务分发
    2.直接交互:同步
        客户端 -> http,rpc,webservice -> 服务端
        常用:restful,webservice,http,rpc
    3.rpc中:
        server:Provider 服务提供者
        client:Consumer 服务消费者
        Stub 存根,服务描述

3.现有框架对比:

xx grpc thrift RMI dubbo hadoopRPC
开发语言 多语言 多语言 java java java
序列化 protobuf thrift格式 Java序列化 hession2 R/Writable
注册中心 false fasle jdk自带 zk等 false
跨语言 true true false false false
服务定义 protobuf thrift文件 Java接口 Java接口 java接口
服务治理 false false false true false

4.核心原理:三部分组成

server      服务提供
client      服务消费
registry    服务注册与发现

5.技术栈:

1.基础:javacore ,maven ,反射
2.动态代理:生成client存根实际调用对象 java动态代理
3.序列化:java对象与二进制数据互转 fastjson
4.网络通信:用来传输序列化后的数据 jetty,URLConnection

6.代码实现:

1.建工程
2.实现序列化模块
3.实现网络模块
4.实现server
5.实现client
6.gk-rpc使用案例

7.创建协议:

D:\git-20191029\customRPC\rpc-proto\src\main\java\pers\li\rpc

8.总结:

问题:对网络协议理解较浅
不足:
    安全性
    服务端处理能力 
    注册中心
    集成能力                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

9.理解:

rpc-proto : 基础协议封装
    Peer:主机+端口
    ServiceDescriptor:服务描述,将会是注册中心中对应的【服务的key值】包含有【类,方法,返回值类型,参数类型数组】,唯一确定一个方法
    Request:请求体,持有【服务描述+请求参数数组】
    Response:默认的响应体封装
rpc_transport: 网络服务封装
    TransportClient:客户端封装【接口+实现】
        1.创建连接
        2.发送数据等待响应:发送inputstream,等待outputstream
        3.关闭连接
    TransportServer:服务端封装【接口+实现】
        1.启动监听: servlet管理
        2.接收请求:接收请求,反序列化获取对象,处理调用,返回数据
        3.关闭监听
rpc-common: 工具类封装
    ReflectionUtils:
        根据class创建对象
        根据class获取该类所有公共方法
        invoke方法调用 : public static Object invoke(Object object, Method method, Object... args)
rpc-codec: 序列化封装【接口+实现】
    Encoder 转二进制
    Decoder 转对象
rpc-server: 服务端封装
    RpcServerConfig:服务配置类
        HTTPTransportServer:默认服务实例类
        JSONEncoder:序列化实例类
        JSONDecoder:反序列化实例类
        port:监听端口
    ServiceInstance:服务的实例 --> 哪个对象暴露出哪个方法
        target:对象
        method:方法
    ServiceManager:管理rpc的所有服务
        Map<ServiceDescriptor, ServiceInstance> services:要将服务描述,服务实例作为key-value存储,便于客户端传来时,能够找到准确地实例,调用正确的方法
        register:服务注册【register(Class<T> interfaceClass, T bean) 】
            接口类 + 对象bean:将对象中的每一个方法都当做一个ServiceInstance注册进map中
        lookup:服务查找【lookUp(Request request)】
            获取请求中的ServiceDescriptor,去map中取出
    ServiceInvoke:【服务的调用】
        invoke(ServiceInstance serviceInstance, Request request):
            通过request的ServiceDescriptor找到服务的实例
            通过反射调用方法,传入参数
            ReflectionUtils.invoke(serviceInstance.getTarget(), serviceInstance.getMethod(),request.getParameters())
    RPCServer:【服务的封装】
        1.设置RpcServerConfig config
        2.反射获取网络实例     ReflectionUtils.newInstance(config.getTransportClass());
        3.反射获取序列化实例   ReflectionUtils.newInstance(config.getEncoderClass());
        4.反射获取反序列化实例 ReflectionUtils.newInstance(config.getDecoderClass());
        5.创建服务调用对象: this.serviceInvoke = new ServiceInvoke();
        6.创建服务管理对象:this.serviceManager = new ServiceManager();
        7.初始化网络实例:this.net.init(config.getPort(), this.handler); 此时只是准备好服务信息,并未开启监听
        
        8.register:服务注册 register(Class<T> interfaceClass, T bean) {serviceManager.register(interfaceClass, bean); }
        9.start:this.net.start 开启
        10.stop:this.net.stop  关闭
        11.handler请求处理:
            1.接收inputStream
            2.反序列化获得Request
            3.根据ServiceManager.lookup(request)找到实例ServiceInstance
            4.通过Object invoke = serviceInvoke.invoke(sis, request);得到响应结果并封装到 response.setData(invoke);
            5.序列化Response
            6.write
rpc-client: 客户端封装