什么是RPC框架,主流的RPC框架有哪些,Golang中如何实现RPC服务
1. RPC协议简介
1.1 什么是RPC协议
- RPC又叫远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议
- RPC是一种使程序能够在不同地址空间中执行子程序或服务的协议。通过RPC,程序可以像调用本地函数一样调用远程服务,从而隐藏了网络通信的复杂性。
- RPC协议允许一台计算机的程序调用另一台计算机的子程序。
1.2 为什么需要RPC协议
- 分布式系统支持:在分布式应用中,服务可能运行在不同的机器上,RPC简化了它们之间的通信。
- 简化开发:开发者可以专注于业务逻辑,而无需处理底层网络细节。
- 模块化:允许将功能分散到多个服务中,方便维护和扩展。
1.3 RPC的优缺点
优点
- 透明性:调用远程服务的方式与调用本地服务类似,开发者无需关心底层实现。
- 跨平台支持:不同系统和编程语言之间可以通过RPC进行通信。
- 易于扩展:可以轻松添加新的服务,而不影响现有服务。
缺点
- 性能开销:网络延迟和数据序列化/反序列化会增加响应时间。
- 故障处理复杂性:网络问题、服务宕机等情况会导致调用失败,需要额外处理。
- 调试困难:远程调用的错误比本地调用更难排查。
1.4 RPC协议的特点
- 序列化:数据在传输前需要序列化为字节流,以便于在网络上传输,常用的格式包括JSON、XML、Protocol Buffers等。
- 同步与异步:RPC可以是同步的(等待调用结果)或异步的(立即返回,不等待结果)。
- 状态管理:RPC调用通常是无状态的,但某些实现可以支持会话状态。
- 安全性:通过加密、认证等方式确保数据在传输过程中的安全性。
2. RPC框架
2.1 Dubbo
- 简介:Dubbo是Java开发的一个流行的RPC框架,广泛应用于Java项目中,集成了大多数服务治理方面的一些组件,支持服务治理,多种序列化协议,支持多种注册中心,自带服务管理中心,缺点是早期不支持跨语言通信,主要应用于Java项目之中。当前最新版本version3.3,已经支持多种语言SDK。
- 项目文档:https://cn.dubbo.apache.org/zh-cn/overview/
- Github地址:https://github.com/apache/dubbo/
2.2 Motan
- 简介:Motan和Dubbo一样也是Java开发的一个流行的RPC框架,广泛应用于Java项目之中,和Dubbo框架一样,早期不支持跨语言特性,后续版本增加了多语言版本,支持服务治理,多种序列化协议,支持多种注册中心,自带服务管理中心,主要应用于Java项目之中。
- 官方文档:https://github.com/weibocom/motan/wiki/zh_overview
- Github地址:https://github.com/weibocom/motan
2.3 Thrift
- 简介:Thrift是一个跨语言轻量级RPC框架,最初是由Facebook开发维护,目前是由Apache开源维护,只支持Thrift协议,框架自身没有实现服务治理和注册组件,需要开发者自行集成。
- 官方地址:https://thrift.apache.org/
- Github地址:https://github.com/apache/thrift
2.4 Grpc
- 简介:Grpc框架是由google开发开源,是一款语言中立、平台中立、开源的远程过程调用系统,支持多语言,Grpc默认使用protocol buffers,是应用最广泛的RPC框架,目前主流的应用程序大都支持和集成了Grpc服务接口,我们在实际开发和使用过程中一般是先定义proto文件,通过protoc来自动创建Grpc服务端。
- 官方地址:https://grpc.io/docs/
- Github地址:https://github.com/grpc/grpc
2.5 Rpcx
- 简介:Rpcx是由国人鸟窝开发维护的一个高性能Rpc框架,主要特点以简单易用,根据文档步骤可以很轻易的集成在自己的项目中,高性能,跨平台,多语言支持,框架层面集成了服务发现,服务治理相关功能。
- 官方地址:https://rpcx.io/
- Github地址:https://github.com/smallnest/rpcx
3. Golang中实现Rpc服务
在Golang中实现Rpc服务非常简单,Golang官方以及一些第三方库都提供了Rpc服务实现方式,接下来我们以Golang官方提供的net/rpc
库来简单的实现一个Golang的Rpc服务。
3.1 net/rpc库说明
- 序列化协议:
net/rpc
默认以encoding/gob
进行数据序列化,Golang独有序列化协议,其他开发语言暂不支持,因此以net/rpc
库开发的Rpc
服务器,支持Golang语言自己内部调用。 - 其他序列化协议:为了多语言通信,GOlang官方在
net/rpc
包下提供了net/rpc/jsonrpc
库,支持以json
的形式进行数据序列化,以实现Rpc
服务跨语言调用。
3.2 基于net/rpc库实现Rpc服务
3.2.1 Rpc服务端
package main
import (
"log"
"net/http"
"net/rpc"
)
// Golang基于net/rpc库实现Rpc服务
type Request struct {
M int
N int
}
type Server struct{}
func (s *Server) Multiply(r Request, res *int) error {
*res = r.M * r.N
return nil
}
// main函数
func main() {
// 服务注册
serv := new(Server)
// 注册serv服务
if err := rpc.Register(serv); err != nil {
log.Panicf("register server error, %s\n", err)
return
}
// 将serv服务绑定到Http服务上
rpc.HandleHTTP()
// 监听HTTP服务
if err := http.ListenAndServe("127.0.0.1:8081", nil); err != nil {
log.Panicf("ListenAndServe error, %s\n", err)
return
}
}
3.2.2 Rpc客户端
package main
import (
"fmt"
"log"
"net/rpc"
)
type Request struct {
M, N int
}
func main() {
// 与远程RPC服务建立连接
conn, err := rpc.DialHTTP("tcp", "127.0.0.1:8081")
if err != nil {
log.Panicf("DialHTTP error, %s\n", err)
return
}
// 调用远程方法
res := 0
req := Request{
M: 10,
N: 20,
}
if err = conn.Call("serv.Multiply", req, &res); err != nil {
log.Panicf("Call func error, %s\n", err)
return
}
fmt.Printf("%d x %d = %d", req.M, req.N, res)
}
4. 总结
主要介绍了什么是RPC,RPC的优缺点;主流RPC框架介绍,Golang中如何借助官方net/rpc
库实现RPC服务于调用。下一篇我们一起来探讨一下在Golang中如何借助Grpc实现RPC服务。