RPC

RPC background

使用场景

Dubbo 的设计目的是为了满足高并发小数据量的 rpc 调用,在大数据量下的性能表现并不好,建议使用 rmi 或 http 协议。

企业间应用集成本质就是如何解决应用如何通信?大批量服务如何定位和管理?RPC,HTTP Restful,以及消息队列都是企业应用间的通信方式,但使用场景不同:

集成方式 使用场景 是否需要解析响应 基于协议 序列化机制
消息队列 组织内部 TCP 二进制
RPC 组织内部 TCP 都可以
HTTP Restful API 外部调用 HTTP 基于文本

Restful端点是微服务里面的概念,主要用于对外(客户)提供服务。RPC主要是对于系统内部模块相互调用。

如Kubernetes中的运行的微服务(一个web endpoint),客户发送一个http连接到运行的微服务,就会返回JSON或者XML数据。而Kubernetes内部比如kubelet访问etcd,则是RPC。

使用Restful的场景往往是更注重API的易用性,客户端一般为本组织的程序,并且希望通过http协议获取到简明的JSON数据。
使用RPC的场景往往是一个机构内部生态系统,生态系统下各不同模块之间的相互调用。

拿电商场景来说,负责购买流程业务开发的同事想要从仓储系统获取到库存量。使用HTTP是可行的,但是基于HTTP的API使用的是文本序列化机制,不如采用二进制序列化方案的RPC效率更高。因此此时采用的是RPC(RPC是一般基于TCP)。而如果公司要公开所出售的商品和相应库存量列表,此时是通过HTTP Restful接口暴露服务,因为客户端更想要简单明了的数据和通用的HTTP。

RPC 实现原理

RPC_第1张图片
RPC实现的关键就在于两点:

  1. 生成负责网络通信的stub(比如Java生成stub类的字节码,需要ASM)
  2. 高效的对象序列化方案

Java内置的序列化方案存在漏洞,参考Effective Java序列化炸弹。

RPC 开源项目

RPC有的公司有跨语言的需求,因为机构内部不可能使用同一种语言开发,目前的RPC方案及语言支持:

RPC方案 支持语言 公司
thrift 跨语言支持 facebook
dubbo 仅java 阿里巴巴

RPC的核心 ---- 序列化方案

RPC的优点就是效率快,特点是对程序运行位置(程序所部署的机器)的无感知性。
比如有两台机器,分别运行着JVM。机器2运行的模块中有这样一段代码:

public class ComplexService{
	public Complex add(Complex a,Complex b){
		return new Complex(a.real+b.real,a.im+b.im);
	}
}

而机器1中的程序想要调用机器2中的这个复数相加的函数,并且希望使用和调用本地代码相同的方式去调用。

//complexService这个引用是需要预先配置的
Complex result=complexService.add(a,b);

为了达到这个目的,运行在不同机器上JVM需要通过TCP/IP协议进行协商通信。协商通信的时候需要把这个复数序列化。序列化的目的就是将对象或者结构体转换为格式化的JSON或者二进制格式,便于发送。

一些RPC解决方案如Thrift,Kyro,Dubbo等都有自己的序列化方法,性能和易用性方面也各有差异。关于各种序列化技术性能对比参考:jvm-serializers

JSON格式比较清晰明了,使用的人还是挺多的。其性能测试参考:java-json-benchmark

Protocol Buffers

以下简称"ProtoBuf"。

你可能感兴趣的:(分布式与微服务)