前言
我们知道 Apache Dubbo 是一个 RPC 框架, 那什么是 RPC 呢?本文主要了解下 RPC 基础。
web应用软件架构的演进
1.单一应用架构 (ORM)
当网站流量很小时,只需要一个应用,将所有功能部署在一起,以减少部署节点和成本。
此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
2.垂直应用架构(MVC)
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。
此时,用于加速前端页面开发的Web框架(MVC)是关键。
3.分布式服务架构 (RPC)
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
4.流动计算架构 (SOA)
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
5.微服务架构(MSA)
当业务系统服务化之后,原本共享的业务被拆分形成可以复用的服务,可以最大程度上避免业务被重复建设、资源连接瓶颈等问题。
此时,用于降低业务的耦合以及提升容错性的微服务框架(MSA)是关键。
RPC 概念
RPC(Remote Procedure Call)即远程过程调用,一种进程间通信方式,允许像调用本地服务一样调用远程服务,它对业务隐藏了底层通信过程(TCP/UDP、打包/解包、序列化/反序列化),主要目的就是让远程服务调用更简单、透明,是分布式服务的基石。
RPC 如何远程调用服务
RPC 调用的流程涉及到哪些通信细节
- 服务消费方(client)调用以本地调用方式调用服务;
- client stub接收到调用后负责将方法、参数等组装编码成能够进行网络传输的消息体;
- client stub找到服务地址,并将消息发送到服务端;
- server stub收到消息后进行解码;
- server stub根据解码结果调用本地的服务;
- 本地服务执行并将结果返回给server stub;
- server stub将返回结果编码打包成消息并发送至消费方;
- client stub接收到消息,并进行解码;
- 服务消费方得到最终结果。
RPC的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。
RPC 核心技术点
动态代理
服务调用者使用的服务实际上是远程服务的本地代理。Java 代理有框中方式:
- jdk 动态代理(Proxy和InvocationHandler)
- 字节码生成(cglib、javassist、asm 、bcel)
尽管字节码生成方式实现的代理更为强大和高效,但代码维护不易,大部分公司实现RPC框架时还是选择动态代理方式。
序列化和反序列化
在网络通信过程中,所有数据都会被转化成字节进行传送,所以为了能够使参数对象在网络中进行传输,需要对这些参数进行序列化和反序列化操作。
- 序列化:将对象序列化为字节流,用于网络传输、数据持久化等用途,也就是编码
- 反序列化:将字节流还原成对象,也就是解码
主流编解码技术:Google的Protobuf、Apache的Thrift、hession、Json、Xstream等等。
通信
RPC框架与具体的协议无关。由于 JDK 自带的 socket 功能较弱,而使用常用的 socket 通信框架,如netty、mina,socket 通信有长连接、短连接、心跳、BIO、NIO等,而 RPC 框架一般选择长链接或者 NIO。
