golang实现rpc远程调用

RPC
        远程过程调用(Remote Procedure Call,缩写为 rpc)是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。 如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。
用通俗易懂的语言描述就是:rpc允许跨机器、跨语言调用计算机程序方法。打个比方,我用go语言写了个获取用户信息的方法getUserInfo,并把go程序部署在阿里云服务器上面,现在我有一个部署在腾讯云上面的php项目,需要调用golang的getUserInfo方法获取用户信息,php跨机器调用go方法的过程就是rpc调用。
golang中如何实现rpc
        在golang中实现rpc非常简单,有封装好的官方库和一些第三方库提供支持。go rpc可以利用tcp或http来传递数据,可以对要传递的数据使用多种类型的编解码方式。golang官方的net/rpc库使用encoding/gob进行编解码,支持tcp或http数据传输方式,由于其他语言不支持gob编解码方式,所以使用net/rpc库实现的RPC方法没办法进行跨语言调用。
        golang官方还提供了net/rpc/jsonrpc库实现rpc方法,json rpc采用rpc进行数据编解码,因而支持跨语言调用。但目前的jsonrpc库是基于tcp协议实现的,暂时不支持使用http进行数据传输。
除了golang官方提供的rpc库,还有许多第三方库为在golang中实现rpc提供支持,大部分第三方rpc库的实现都是使用protobuf进行数据编解码,根据protobuf声明文件自动生成rpc方法定义与服务注册代码,在golang中可以很方便的进行rpc服务调用。
go的net/rpc库
        下面的例子演示一下如何使用golang官方的net/rpc库实现rpc方法,使用http作为rpc的载体,通过net/http包监听客户端连接请求。
$GOPATH/src/test/rpc/rpc_server.go

 

上述服务端程序运行后,将会监听本地的8095端口,我们可以实现一个客户端程序,连接服务端并实现rpc方法调用。
$GOPATH/src/test/rpc/rpc_client.go

 

net/rpc/jsonrpc库
上面的例子我们演示了使用net/rpc实现rpc的过程,但是没办法在其他语言中调用上面例子实现的rpc方法。所以接下来的例子我们演示一下使用net/rpc/jsonrpc库实现rpc方法,此方式实现的rpc方法支持跨语言调用。
$GOPATH/src/test/rpc/jsonrpc_server.go

 

上述服务端程序启动后,将会监听本地的8096端口,并处理客户端的tcp连接请求。我们可以用golang实现一个客户端程序连接上述服务端并进行rpc调用。
$GOPATH/src/test/rpc/jsonrpc_client.go

 

protorpc库
为了实现跨语言调用,在golang中实现rpc方法的时候我们应该选择一种跨语言的数据编解码方式,比如JSON,上述的jsonrpc可以满足此要求,但是也存在一些缺点,比如不支持http传输,数据编解码性能不高等。于是呢,一些第三方rpc库都选择采用protobuf进行数据编解码,并提供一些服务注册代码自动生成功能。下面的例子我们使用protobuf来定义rpc方法及其请求响应参数,并使用第三方的protorpc库来生成RPC服务注册代码。
首先,需要安装protobuf及protoc可执行命令,可以参考此篇文章:protobuf快速上手指南
然后,我们编写一个proto文件,定义要实现的rpc方法及其相关参数。
$GOPATH/src/test/rpc/pb/arith.proto

 

接下来我们需要根据上述定义的arith.proto文件生成rpc服务代码。
要先安装protorpc库:go get github.com/chai2010/protorpc
然后使用protoc工具生成代码:protoc –go_out=plugin=protorpc=. arith.proto
执行protoc命令后,在与arith.proto文件同级的目录下生成了一个arith.pb.go文件,里面包含了rpc方法定义和服务注册的代码。
基于生成的arith.pb.go代码我们来实现一个rpc服务端
$GOPATH/src/test/rpc/protorpc_server.go

 

运行上述程序,将会监听本地的8097端口并接收客户端的tcp连接。
基于ariti.pb.go再来实现一个客户端程序。
$GOPATH/src/test/protorpc_client.go

 

如何跨语言调用golang的rpc方法
上面的三个例子,我们分别使用net/rpc、net/rpc/jsonrpc、protorpc实现了golang中的RPC服务端,并给出了对应的golang客户端RPC调用示例,因为JSON和protobuf是支持多语言的,所以使用jsonrpc和protorpc实现的RPC方法我们是可以在其他语言中进行调用的。下面给出一个php客户端程序,通过socket连接调用jsonrpc实现的服务端RPC方法。
$PHPROOT/jsonrpc.php

 

其他rpc库
除了上面提到的三种在golang实现rpc的方式外,还有一些其他的rpc库提供了类似的功能,比较出名的有google开源的grpc,但是grpc的初次安装比较麻烦,这里就不做进一步介绍了,有兴趣的可以自己了解。
go相关的rpc框架
grpc,thrift

发表评论

电子邮件地址不会被公开。 必填项已用*标注