RPC与gRPC

143 阅读3分钟

什么是RPC

RPC——Remote Process Calls,”远程过程调用“是相对于”本地过程调用“的概念。

简单地说,我们写了一个main()函数和一个miao()函数,在main()函数中调用miao()函数,这个过程就是本地调用。

package main

import (
	"fmt"
)

func main() {
	// 本地过程调用
	miao("leo")
}

func miao(name string) {
	fmt.Println("I am %s, miao, miao, miao...", name)
}

我们之所以可以直接在main()中调用miao()函数,是因为它们运行在同一个机器,同一个进程中。那么如果我们没有一只猫,还想听猫叫,想要调用别人的机器、进程中的miao()函数该怎么办呢?

这就涉及到以下几个问题:

a. 通信问题。我们要调用别人机器,别的进程中的东西,这个过程发生在网络上,是需要建立网络连接来沟通的。所有的数据都要通过网络传输,因此需要一个网络传输层。RPC本身没有对网络传输层使用的协议作出规定,但是大部分RPC框架使用的都是TCP协议,其实也可以使用UDP,而gRPC直接用了HTTP2。

b. 寻址问题。我们的应用怎么告诉RPC框架,要连接的远程服务器IP,端口是什么,要调用的方法名称是什么?比如基于Web服务协议栈的RPC,需要提供一个endpoint URI。

c. 数据发送与接收。我们的应用发起RPC调用时,方法的参数是通过底层的网络协议(eg, TCP)传递到远程服务器的,而网络协议都是基于二进制的,因此我们内存中的参数值需要先序列化(Serialize)成二进制的形式再发送给远程服务器,远程服务器接收到请求后,再反序列化(Unserialize),恢复成内存中的表达方式。可见,RPC调用过程中函数参数是以二进制流的方式进行传输的,调用方和被调用方即使不是同一种编程语言也可以完成这个过程。

广义地讲,实现了这三个机制,就实现了RPC调用了。常见的RPC框架有 Dubbo, Motan, Tars, Spring Cloud, gRPC, Thrift...

RPC调用在分布式系统,微服务架构中使用非常广泛。

什么是gRPC?

了解了RPC的概念后,让我们来看一个近年来很火的gRPC。

gRPC是一种现代的,开源的远程调用(RPC)框架。

既然gRPC是一种RPC框架,那它肯定实现了上面提到的三个问题。

a. 通信问题->传输层使用HTTP/2.

b. 寻址问题->需要提供endpoint URI.

c. 数据发送与接收->默认使用Protocol Buffers,谷歌的开源序列化框架。

gRPC的理念是,让客户端应用程序可以像调用本地对象一样调用远程服务器上的方法。gRPC以及其他很多RPC系统都是基于定义服务的思想,就是指定可以远程调用的方法以及方法参数,返回值类型。在Server端实现了这些接口来处理客户端请求。

在客户端有一个 stub, 这个stub提供了和server端相同的方法,通过 protocol buffer 序列化反序列化,gRPC客户端和服务器可以在各种环境中运行并相互通信,且可以使用支持gRPC的任意语言编写。

目前支持gRPC的语言有Golang, Java, Python, c++, c# ...,gRPC的文档也很完善,参考这里grpc.io/docs/langua… 可以查看具体语言的demo。

祝gRPC之旅愉快~