type
status
date
slug
summary
tags
category
icon
password
Sub-item
Last edited time
Oct 12, 2023 01:01 PM
Parent item
领域
使用JSON-RPC编码
标准库的RPC默认采用Go语言特有的gob编码,无法和其他服务互通。官方自带有一个
net/rpc/jsonrpc
包,支持jsonrpc格式的编码只要将客户端和服务端的序列化部分替换掉即可
创建客户端就变成:
创建服务端就变成:
底层通信的数据(通过nc命令查看)就会变成:
可以看到出具传输的格式是json-rpc定义的格式。只要其他服务都遵循这种格式,就能实现rpc通信了。
使用HTTP协议
需要构造读写器, 从body中读, 从response中写
服务需要配置API路径, 上面例子是jsonRPC,模拟一次RPC调用的过程就是向该链接发送一个json字符串:
使用PorotoBuf编码
无论是gob还是jsonrpc编码,都是自带数据格式描述,这样无法最大限度压缩数据长度,而ProtoBuf协议没有数据类型定义放到编码外面,提高了压缩率和传输效率,另外将Protobuf和RPC结合在一起使用,将数据定义放在代码之外,客户端和服务端使用同一个定义文件,便于保证交互接口的统一。唯一的代价是数据编码和解码必须依赖外部格式解析文件的定义
Protobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言。
编写proto文件
Protobuf编码通过成员的唯一编号来绑定对应的数据,因此Protobuf编码后数据的体积会比较小。
生成pb文件
根据proto文件,就可以生成rpc相关的接口参数数据定义、接口定义和rpc功能封装了。开发人员只需要关心具体接口的业务逻辑就行, 实现了业务逻辑和技术框架的解耦。
pb文件依赖于不同的编程语言,使用protoc工具时需要指定语言类型,执行下面命令:
protoc --go_out=. hello.proto
工具protoc并没有内置编译生成golang代码的功能,该功能需要通过插件实现,proptoc根据参数
—go_out
会去寻找protoc-gen-go插件, 调用该插件的编译功能执行后生成hello.pb.go文件,生成的代码中包括如下几个功能:
- 把消息的定义转换为了结构体, 并封装了读写方法
- 注册消息类型到protobuf协议
- 对数据的编解码提供了解析文件(
fileDescriptor_61ef911816e0a8ce
),并注册到protobuf协议
服务端的接口实现需要同步更新,之前的string类型变成了新的String结构,在服务端对Hello方法可以更新为:
注意,工具只生成了数据相关的代码,没有为
HelloService
服务生成相应的rpc功能代码(数据编解码,业务接口,客户端rpc调用等),甚至都没有生成像上面介绍的最简单的基于tcp/http通信的rpc功能框架,这是因为protoc编译器并不知道该如何为HelloService服务生成代码。rpc通信除了要解决传输协议和报文编码问题,还需要解决一系列的可用性问题,例如,连接超时了怎么办?是否支持异步请求和并发?是否支持双向发流?
于是就产生了很多RPC框架:
gRPC
、rpcx
、go-micro
,在protoc-gen-go内部已经集成了一个名字为grpc
的插件,可以针对gRPC生成代码:在生成的代码中多了一些类似
HelloServiceServer
、HelloServiceClient
的新类型。这些类型是为gRPC服务的。