浅谈RPC

一、RPC概念

RPC(Remote Procedure Call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想。

RPC 是一种技术思想而非一种规范或协议,常见 RPC 技术和框架有:

二、目前流行的开源 RPC 框架

应用级的服务框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
通信框架:MINA 和 Netty。
Facebook 的 Thrift、Twitter 的 Finagle 等。

重点介绍三种:

  • Dubbo:国内最早开源的 RPC 框架,极为出名,由阿里巴巴公司开发并于 2011 年末对外开源,仅支持 Java 语言。协议和序列化框架都可以插拔是极其鲜明的特色。
  • gRPC:Google 于 2015 年对外开源的跨语言 RPC 框架,支持多种语言。RPC 框架是基于 HTTP 协议实现的,底层使用到了 Netty 框架的支持。
  • Thrift:最初是由 Facebook 的开源 RPC 框架,主要是一个跨语言的服务开发框架,2007 年贡献给了 Apache 基金,成为 Apache 开源项目之一,支持多种语言。用户只要在其之上进行二次开发就行,应用对于底层的 RPC 通讯等都是透明的。不过这个对于用户来说需要学习特定领域语言这个特性,还是有一定成本的。

Motan:新浪微博内部使用的 RPC 框架,于 2016 年对外开源,仅支持 Java 语言;
Tars:腾讯内部使用的 RPC 框架,于 2017 年对外开源,仅支持 C++ 语言;
Spring Cloud:国外 Pivotal 公司 2014 年对外开源的 RPC 框架,仅支持 Java 语言;

三、RPC 框架的重要组成

一个 RPC 的核心功能主要有 5 个部分组成,分别是:客户端、客户端 Stub、网络传输模块、服务端 Stub、服务端等:

  • 客户端(Client):服务调用方。
  • 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端。
  • 服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。
  • 服务端(Server):服务的真正提供者。
  • Network Service:底层传输,可以是 TCP 或 HTTP。
    在这里插入图片描述

四、RPC 框架实现

1、RPC调用流程:

(1). 服务消费方(client)以本地调用方式调用服务;
(2). client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
(3). client stub找到服务地址,并将消息发送到服务端;
(4). server stub收到消息后进行解码;
(5). server stub根据解码结果 反射调用 本地的服务;
(6). 本地服务执行并将结果返回给server stub;
(7). server stub将返回结果打包成消息并发送至消费方;
(8). client stub接收到消息,并进行解码;
(9). 服务消费方得到最终结果。

2、RPC 框架实现需要使用到的技术

1)服务注册中心(寻址)

服务发现与注册的核心是,服务启动时,将服务名称和服务地址写入到配置中心,客户端调用的时候,先从服务注册中心读取去查询对方服务都有哪些实例,所要调用服务的服务器地址,如果有多个,进一步处理负载均衡问题,连接服务器并调用。

Dubbo 的服务注册中心是可以配置的,官方推荐使用 Zookeeper。

2)动态代理问题

服务调用者用的服务实际是远程服务的本地代理,其实就是通过动态代理来实现。Java里至少提供了两种方式来提供动态代码生成,一种是jdk动态代理,另一种是字节码生成,动态代理相比字节码生成使用起来更方便,但动态代理方式在性能上比字节码要差,而字节码生成在代码可读性上要差很多。

生成 client stub和server stub需要用到 Java 动态代理技术 ,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。

3)序列化问题

客户端怎么把参数值传给远程的函数呢?在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参数。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。只有二进制数据才能在网络中传输,序列化和反序列化的定义是:

  • 将对象转换成二进制流的过程叫做序列化
  • 将二进制流转换成对象的过程叫做反序列化

这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。

可以使用Java原生的序列化机制,但是效率非常低,推荐使用一些开源的、成熟的序列化技术,例如:protobuf、Thrift、hessian、Kryo、Msgpack

4)网络通讯问题(NIO )

所有的数据都需要通过网络传输,因此就需要有一个网络传输层。因此,它所使用的协议其实是不限的,能完成传输就行,在 RPC 中可选的网络传输方式有多种,可以选择 TCP 协议、UDP 协议、HTTP 协议。

尽管大部分 RPC 框架都使用 TCP 协议,但其实 UDP 也可以,而 gRPC 干脆就用了 HTTP2。可以自己写 Socket,或者用 Asio,ZeroMQ,Netty 之类。当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推荐使用Netty 作为底层通信框架。

RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,实现复杂。
HTTP 主要用于对外的异构环境,浏览器接口调用,App 接口调用,第三方接口调用等。
RPC 使用场景(大型的网站,内部子系统较多、接口非常多的情况下适合使用 RPC):
长链接。不必每次通信都要像 HTTP 一样去 3 次握手,减少了网络开销。
注册发布机制。RPC 框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。
安全性,没有暴露资源操作。
微服务支持。就是最近流行的服务化架构、服务化治理,RPC 框架是一个强力的支撑。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只IT攻城狮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值