V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
CyouYamato
V2EX  ›  程序员

关于 grpc, proto 的疑惑

  •  
  •   CyouYamato · 2023-12-20 18:43:48 +08:00 · 2415 次点击
    这是一个创建于 370 天前的主题,其中的信息可能已经有所发展或是发生改变。

    好奇为什么 proto 文件需要定义各种参数?直接参数类型为 string 值为 json 不可以吗? message Person { string name = 1; int32 age = 2; }

    message Person { string params = 1; }

    20 条回复    2024-01-01 21:40:37 +08:00
    dayeye2006199
        1
    dayeye2006199  
       2023-12-20 18:52:21 +08:00 via Android   ❤️ 1
    因为鬼知道 params 里有什么
    helone
        2
    helone  
       2023-12-20 18:54:16 +08:00   ❤️ 1
    一个是传输层面,你直接一个参数肯定会显著增加数据包大小,第二个就是 json encode decode 其实也需要时间,本身 grpc proto 定义各种参数就是为了减少这种耗时
    XCFOX
        3
    XCFOX  
       2023-12-20 18:57:36 +08:00   ❤️ 1
    Protocol Buffers 是强类型的,能让通讯双方明确数据结构和类型,proto 文件本身具有文档的功能。
    json 只是单纯的无类型数据,按 message Person { string params = 1; } 这么写过两个礼拜你自己都不知道 params 里有什么。
    willchen
        4
    willchen  
       2023-12-20 19:05:36 +08:00
    短小精悍
    Kaisar
        5
    Kaisar  
       2023-12-20 19:10:00 +08:00   ❤️ 2
    照这么说直接传 json 不就完了
    XCFOX
        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
    silentsky
        7
    silentsky  
       2023-12-20 19:29:28 +08:00 via Android
    就是要去掉 JSON 的 key 你还想把它塞进去 怎么想的
    BingGan
        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 文件当密码本,记录字段和编号的对应关系
    gzlock
        9
    gzlock  
       2023-12-20 19:54:20 +08:00
    protobuf 挺好用的啊,我在自己的二进制文件格式里用上了 protobuf

    https://github.com/whimsy-ai/ilp_file_codec#the-ilp-file-structure
    cloudzhou
        10
    cloudzhou  
       2023-12-20 19:58:20 +08:00
    @XCFOX 你提的这些问题,在一个成熟框架里面,业务开发根本不需要关注
    mason961125
        11
    mason961125  
       2023-12-20 19:59:48 +08:00
    @XCFOX 推广请去推广区域,不要污染正常讨论。
    SilentRhythm
        12
    SilentRhythm  
       2023-12-20 20:05:19 +08:00
    protobuf 对比 json ,在传输层解决的是传递内容大小的问题,进而提高传输效率。
    假如你 json 有一个 key 命名长度 50 ,还是个 20 长度数组,那你使用 protobuf 就节省了接近 1000 个字符的传输量了。
    iOCZS
        13
    iOCZS  
       2023-12-20 20:34:00 +08:00
    有了 proto 文件,可以省下 key 的代价,只要发送序号就行。编码方式其实就那些,还想继续扣消耗,那就查表喽。这种思想都是相通的,包括 http2 的请求头压缩,也是类似的查表。
    oswinw
        14
    oswinw  
       2023-12-20 21:20:41 +08:00 via Android
    没指令集的时候,prorobuf 和 json 序列化反序列化开销都挺大的
    oswinw
        15
    oswinw  
       2023-12-20 21:21:29 +08:00 via Android
    @oswinw 说错了,是效率差异很大
    deorth
        16
    deorth  
       2023-12-20 21:36:02 +08:00 via Android
    那你用 jsonrpc 不就完了
    beneo
        17
    beneo  
       2023-12-21 04:50:30 +08:00 via iPad
    gRPC 是想着法子在网卡打满的情况下支持更多请求,和你的追求有点不一样
    CyouYamato
        18
    CyouYamato  
    OP
       2023-12-21 10:16:04 +08:00
    感谢,大佬们的回复。
    我用的是 ts ,因为 proto3 不支持 optional repeated,而生成工具这边用的是:ts-proto 。生成后的代码要么全是可选,要么就是自己手动指定的可选,或者再加上 message 可选(也不支持可选数组)。而且 proto 作者明确表示不会考虑支持 optional repeated ,非常疑惑。
    为何不用 http ,是组长测试线上 http 维持连接只能在一分钟左右,而 grpc 可以很久。我们业务需要维持很长时间的远程调用。个人觉得 http 和 grpc 底层都是 tcp,应该也能维持很久。
    changz
        19
    changz  
       2023-12-21 12:54:53 +08:00 via Android
    纠正一下 protobuf 在 3.15 后是支持 optional 的
    julyclyde
        20
    julyclyde  
       358 天前
    @CyouYamato http 是由双方其中之一主动掐断 tcp 的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3015 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:46 · PVG 21:46 · LAX 05:46 · JFK 08:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.