• RPC框架基础概念理解以及使用初体验


    RPC:Remote Procedure Call(远程服务调用)

    RPC是做什么的

    通过RPC框架机器A某个进程可以通过网络调用机器B上的进程方法,就像在本地上调用一样。
    RPC可以基于HTTP或者TCP协议通信,TCP协议相对性能较高。

    调用图示(引用zhanglijun童鞋的图)

    image

    图片描述:

    1. client发出调用方法(服务)的请求
    2. client stub作为中转站,进行请求接口、方法、参数以及服务地址、请求Id的封装,包装成RequestMessage对象、序列化——编码,最后传输到网络上去
    3. 服务端(service)经过网络接受到RequestMessage
    4. 首先server stub进行字节流的反序列化、解析requestMessage——解码,最后将请求转发给server
    5. server调用method(...),返回结果给server stub
    6. server stub将result、返回状态码、请求id等进行包装成ResponseMessage、序列化——编码、传输
    7. client stub得到字节流,进行反序列化、解析ResponseMessage——解码,将结果返给client
    8. client最终得到结果

    RPC框架就是将2-7这几个步骤封装起来,帮忙处理网络IO、编解码、序列化、服务寻址等工作,这些工作对于调用方和服务方都是透明的。由此,我们也可以得出结论,我们就需要使用代码实现2-7步骤所需要处理的工作。下面列举实现一个轻量级RPC框架所需要解决的几个问题。

    RPC框架的实现需要解决的几个问题

    如果想实现一个轻量级rpc框架需要解决什么问题呢:

    请求封装问题

    机器A想要调用机器B上面的方法method(),那么A机器就需要详细描述自己的需求——要调用那个ip上那个端口的进程、调用哪个service,这些都需要描述清楚。

    详细如下:

    • 接口名称,一个接口提供一种服务,比如HelloworldService
    • 方法名称,定位一个接口内的某个方法
    • 参数——类型与值,client调用就需要client指定入参,服务端是肯定不知道这些的
    • 超时时间
    • requestId,每一个client发出请求时都需要绑定一个唯一指定requestId,这是因为在并发请求的时候一个服务方可能服务多个client的请求,有了这个requestId,client stub才能将返回结果发放给特定的请求线程而不会混淆。

    返回消息对象封装问题

    • 返回值
    • 状态code,表示这次请求成功与否
    • requestid

    序列化的问题

    网络IO需要传输请求消息对象以及响应消息对象,这样才能达到双方通信的目的。但是网络是以字节(byte)准确的说是比特传输信息的,因此需要一种技术将对象转换成字节(序列化),以及再将字节转换成对象(反序列化)。java自身是有序列化工具的,借助ObjectOutputStream等类就可以序列化对象。但是他的性能、拓展性都不是很好,因此一般借助于第三方的序列化工具

    目前,互联网公司主流使用protobufthriftjacksonhessian

    网络通信问题

    消息序列化之后就是网络通信了,使用java nio是可以实现一个通信框架的,但这属于高难度动作——专家模式。就码农way而言,使用netty通信框架,省事省力,经过测试完善的框架也不容易出错

    服务发布的问题

    一般情况,如果客户端依赖的服务挂掉或者切换地址等,那么客户端可能就无法工作或者需要改变配置。为了能够达到自动切换服务、寻址等问题,就需要一个服务注册和发现功能的框架。市面上流行的是zookeeper,他可以将上线的服务注册进去,提供给客户端调用。zookeeper会不断对服务进行心跳检测,一旦服务挂掉,就会在注册中心把他消掉。客户端可以在注册中心切换到其他可用的服务

    zookeeper的服务注册格式:/{service}/{version}/{ip:port}

    关于RPC框架的初体验

    这里并不是商用的RPC框架,没有服务治理、插件支持等功能,使用的是@黄勇写的轻量级分布式 RPC 框架,目的在于理解rpc框架核心代码的功能模块结构、相关技术选型以及如何运行等几个问题

    关于框架的几点理解

    • rpc-sample-api模块,定义了服务接口,这个代码无论客户端和服务端都需要用到的
    • rpc-sample-server模块,对rpc-sample-api的接口进行了实现,启动RpcBootstrap类,就会将rpc-server模块写的RPCServer和注入容器中。这个模块相当于前面LBS大大图片里的server端,真正提供服务的实现的模块
    • rpc-server模块,相当于server stub,他负责将扫描到的被@RpcService注解的类注册到zookeeper,对请求、返回值消息进行序列化、编解码,处理请求等
    • rpc-client模块,就相当于client stub,他负责将client的请求进行编码,发送出去,到zookeeper注册中心去发现可用服务,进行调用
    • rpc-register-zookeeper模块,该模块的ZookeeperServiceDiscovery类为rpc-client模块提供服务发现功能。而zookeeperServiceRegistry类为rpc-server模块提供了服务注册的功能。其实就是实例化一个ZkClient对zookeeper服务进行访问,然后对zookeeper进行注册服务和发现服务
    • rpc-common模块,定义了一些工具类和消息对象。消息对象用于封装请求和返回值消息,工具类主要用于序列化、编解码等功能

    最后,由于本人之前并没有对nettyprotobuf等工具有详细了解,代码细节无法详述,这里只是简单地归纳出该框架的几点模块关系以及作用

    运行步骤

    这里主要是本人运行该框架的几个步骤,其实非常简单

    • 下载源码到IDEA,地址https://gitee.com/huangyong/rpc.git
    • 安装、启动zookeeper服务,不了解的童鞋可以参考 zookeeper安装和使用 windows环境
    • 启动rpc-server,就是rpc-sample-server下的RpcBootstrap类即可,这边服务端就算启用了

    image

    • 接下来运行rpc-sample-client下面的几个类,可以看到客户端代码其实是通过RpcProxy.create(...)获取实例,并得到了返回值

    image

    小结

    本文总结了RPC服务是做什么的以及RPC框架相关的几个概念,接下来描述了如果我们自己写RPC框架需要解决的几个问题。并且使用@黄勇童鞋的开源demo,进行rpc使用的初体验,勉强对rpc框架有了基本的认识。如果想深入使用、了解的童鞋可以尝试使用阿里的hsf、谷歌的gRpc构建自己的微服务应用或者分布式计算等

    参考

    你应该知道的RPC原理

    轻量级分布式 RPC 框架

  • 相关阅读:
    极大似然估计
    python模块的安装
    变异检测
    泰勒公式
    shell关于变量的操作
    Hadoop安装教程
    关于连接linux被拒
    靶向药
    层次聚类
    基因芯片原理
  • 原文地址:https://www.cnblogs.com/Franken-Fran/p/rpc_fornoob.html
Copyright © 2020-2023  润新知