好奇为什么 proto 文件需要定义各种参数?直接参数类型为 string 值为 json 不可以吗? message Person { string name = 1; int32 age = 2; }
message Person { string params = 1; }
1
dayeye2006199 2023-12-20 18:52:21 +08:00 via Android 1
因为鬼知道 params 里有什么
|
2
helone 2023-12-20 18:54:16 +08:00 1
一个是传输层面,你直接一个参数肯定会显著增加数据包大小,第二个就是 json encode decode 其实也需要时间,本身 grpc proto 定义各种参数就是为了减少这种耗时
|
3
XCFOX 2023-12-20 18:57:36 +08:00 1
Protocol Buffers 是强类型的,能让通讯双方明确数据结构和类型,proto 文件本身具有文档的功能。
json 只是单纯的无类型数据,按 message Person { string params = 1; } 这么写过两个礼拜你自己都不知道 params 里有什么。 |
4
willchen 2023-12-20 19:05:36 +08:00
短小精悍
|
5
Kaisar 2023-12-20 19:10:00 +08:00 2
照这么说直接传 json 不就完了
|
6
XCFOX 2023-12-20 19:21:28 +08:00
借楼吐槽一下 gRPC ,用着是真的麻烦:
1. 每次新加函数都要编写 .proto 文件,再重新代码生成; 2. protobuf 语法也很繁琐,在语言里序列号反序列化也麻烦; 3. 没有内置的负载均衡方案,需要另外实现或者网络配置; 马上 2024 年了,推荐使用 NATS 作为远程调用的方案: ✅使用 json ,简单高效 ✅云原生、轻松水平扩展、高性能,服务与 NATS 之间始终保持连接,省去了反复建立 TCP 连接的开销 ✅内置负载均衡、服务发现 ✅可选的消息队列、键值存储 https://nats.io/ https://github.com/nats-io/nats.go/blob/main/micro/README.md |
7
silentsky 2023-12-20 19:29:28 +08:00 via Android
就是要去掉 JSON 的 key 你还想把它塞进去 怎么想的
|
8
BingGan 2023-12-20 19:40:13 +08:00 via iPhone 1
这个问题就是在问 protobuf 和 json 的区别嘛,随便一搜就有。
头一个缺点是非字符串的编码低效。比如 int 字段的值是 12345 ,内存表示只占两个字节,转成 JSON 却要五个字节。bool 字段则占了四或五个字节。 再一个缺点就是信息冗余。同一个接口同一个对像,只是 int 字段的值不同,每次都还要传输”int”这个字段名。 等等,这是缺点吗?是!可 JSON 为什么会有这些毛病呢?因为 JSON 在可读性和编码效率之间选择了可读性,所以效率方面做了一定的牺牲。 好了,现在人们觉得效率是主要矛盾了,那就必然会牺牲可读性。为此,Protobuf 一方面选用了 VarInts 对数字进行编码,解决了效率问题;另一方面给每个字段指定一个整数编号,传输的时候只传字段编号,解决了冗余问题。更多细节可参考的另一篇文章 在传输的时候只传了字段编号固然可以提高传输效率,但接收方如何知道各个编号对应哪个字段呢?只能事先约定了。就像当年地下工作者一样,一人拿一个密码本。Protobuf 使用 .proto 文件当密码本,记录字段和编号的对应关系 |
9
gzlock 2023-12-20 19:54:20 +08:00
protobuf 挺好用的啊,我在自己的二进制文件格式里用上了 protobuf
https://github.com/whimsy-ai/ilp_file_codec#the-ilp-file-structure |
11
mason961125 2023-12-20 19:59:48 +08:00
@XCFOX 推广请去推广区域,不要污染正常讨论。
|
12
SilentRhythm 2023-12-20 20:05:19 +08:00
protobuf 对比 json ,在传输层解决的是传递内容大小的问题,进而提高传输效率。
假如你 json 有一个 key 命名长度 50 ,还是个 20 长度数组,那你使用 protobuf 就节省了接近 1000 个字符的传输量了。 |
13
iOCZS 2023-12-20 20:34:00 +08:00
有了 proto 文件,可以省下 key 的代价,只要发送序号就行。编码方式其实就那些,还想继续扣消耗,那就查表喽。这种思想都是相通的,包括 http2 的请求头压缩,也是类似的查表。
|
14
oswinw 2023-12-20 21:20:41 +08:00 via Android
没指令集的时候,prorobuf 和 json 序列化反序列化开销都挺大的
|
16
deorth 2023-12-20 21:36:02 +08:00 via Android
那你用 jsonrpc 不就完了
|
17
beneo 2023-12-21 04:50:30 +08:00 via iPad
gRPC 是想着法子在网卡打满的情况下支持更多请求,和你的追求有点不一样
|
18
CyouYamato OP 感谢,大佬们的回复。
我用的是 ts ,因为 proto3 不支持 optional repeated,而生成工具这边用的是:ts-proto 。生成后的代码要么全是可选,要么就是自己手动指定的可选,或者再加上 message 可选(也不支持可选数组)。而且 proto 作者明确表示不会考虑支持 optional repeated ,非常疑惑。 为何不用 http ,是组长测试线上 http 维持连接只能在一分钟左右,而 grpc 可以很久。我们业务需要维持很长时间的远程调用。个人觉得 http 和 grpc 底层都是 tcp,应该也能维持很久。 |
19
changz 2023-12-21 12:54:53 +08:00 via Android
纠正一下 protobuf 在 3.15 后是支持 optional 的
|
20
julyclyde 358 天前
@CyouYamato http 是由双方其中之一主动掐断 tcp 的
|