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

求教各位后端大佬,用 gRPC 来实现 TS 与 Python 服务之间的通信时遇到了问题

  •  
  •   superhot · 2025 年 2 月 27 日 · 2692 次点击
    这是一个创建于 325 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目的

    实现后端微服务架构中 TS 与 Python 服务之间的通信,希望能通过维护同一套类型定义/ Schema 保证 single source of truth ,提高接口可维护性。

    尝试过的方案

    1. 最简单的方案,Python 服务用 Flask 实现普通的 REST API 来对其他模块提供服务。问题是一方接口定义更改时,另一方需要同步更改,如果是纯 TS 项目的话,得益于类型信息共享,先改类型定义,所有受影响的地方都能及时发现,后改相关代码就很方便,也比较安心,但如果是多语言的话做不到这点
    2. 借此机会想试试 RPC 替代 REST ,于是尝试了一下 gRPC ,本身多语言支持,还有通用统一的 Protobuf ,看上去很美好,然而可能是我太菜不熟悉,感觉这玩意用起来槽点太多了……

    使用 gRPC 时遇到的问题

    1. 首先最让我感到意外的一点是,那么多官方支持的语言里面,居然没有 JS (还是在连 Dart 和 Ruby 都有的情况下)。虽然有个 grpc/grpc-node,但对 JS 生态的支持看上去不是特别理想
    2. Protobuf 生成的代码质量一言难尽:
      1. 在 TS 项目中,想按照官方文档里的例子那样使用 @grpc/grpc-js 的话,需要自动生成类型定义。找了一圈,发现只有 @grpc/proto-loader 自带的 proto-loader-gen-types 生成的还算可用,然而还是有坑,比如引入路径中没有文件扩展名,而在 TS 中使用 ESM + module": "node16" 时文件扩展名是强制的,所以还是需要手动修改生成的代码。另外有个 @bufbuild/protobuf,号称是唯一一个全部通过 Protobuf 兼容性测试的,结果生成的东西 @grpc/grpc-js 压根用不了,只能用他们的配套库 @connectrpc/connect,说是兼容 gRPC ,也只是客户端部分可以发起 gRPC 而已

      2. protoc 生成的 Python 代码也有引入路径问题,如果文件不在根目录下,就会报错找不到模块,于是你还是需要手动修改自动生成的代码

      3. 官方文档太差了,没有更多用例来解释真实场景里是什么样的,比如服务端的部分:

        server.add_insecure_port("[::]:" + PORT)
        
        server.bindAsync(
            `0.0.0.0:${PORT}`,
            gRPC.ServerCredentials.createInsecure(),
            (err, port) => {},
        );
        

        这都 insecure 了,那生产环境中想 secure 该怎么办?

    上面的问题 GitHub 也有相关 Issue 讨论,但到目前为止似乎都不了了之了。想问一下有相关经验的佬们:

    1. 我这个需求用 gRPC 是否合适?除此之外还有其他解决方案吗?
    2. 在 TS 和 Python 下,正确的使用姿势分别是什么?除了裸用官方的库 @grpc/grpc-js/grpcio之外,还有其他基于 gRPC 的更好用的框架吗?
    21 条回复    2025-02-28 15:12:28 +08:00
    FlashEcho
        1
    FlashEcho  
       2025 年 2 月 27 日
    用 openapi ,然后生成 ts/python 客户端代码?感觉使用应该简单一点(@hey-api/openapi-ts 和 openapi-python-client ),方案比 grpc 简单点,都是 restful api ,不过性能肯定是比不了了
    doublespout
        2
    doublespout  
       2025 年 2 月 27 日
    @chesha1 这个方案靠谱,jsonschema 库还是稳定的
    julyclyde
        3
    julyclyde  
       2025 年 2 月 27 日
    用 protobuf 也依然需要另一端同步修改吧
    难道你不用给 proto 文件就可以直接用?
    jworg
        4
    jworg  
       2025 年 2 月 27 日
    @grpc/grpc-js 我记得是动态 hook proto 文件,类型检查的很好,什么时候退化了吗。gRPC.ServerCredentials.createInsecure() 这一句只是指 grpc 的 tcp 是裸传输的,能中间抓包然后 proto 反解到传输的是什么。要加 tls ,得使用 grpc.ServerCredentials.createSsl() 的方法。
    jworg
        5
    jworg  
       2025 年 2 月 27 日   ❤️ 1
    从楼主的整个思路来看,还是 rest api 吧,整个查资料的深度不足以应付后面的 grpc 相关的更大的坑。
    nomagick
        6
    nomagick  
       2025 年 2 月 27 日
    什么是 gRPC, 就是说 Google RPC, 咱要不是能和 Google 比划比划的话,还是老老实实 HTTP 吧
    jworg
        7
    jworg  
       2025 年 2 月 27 日
    python 的那个导入问题,翻了翻书签,应该和这个 issue 有关系 https://github.com/protocolbuffers/protobuf/issues/1491 用 google 的东西,你得顺从 google 那一套,并且勤翻 issue 区和源码。
    TJT
        8
    TJT  
       2025 年 2 月 27 日
    用 ts-proto 更好,我们已经大范围使用了
    Maboroshii
        9
    Maboroshii  
       2025 年 2 月 27 日
    grpc 太复杂了,依赖库版本和 protoc 也一直更新,保不齐哪天就不兼容了,生成出来的代码每次 diff 一大片也挺难受的(我这边是 golang 用的,改旧项目的 grpc 简直爆炸,根本就一点都不想维护)。 简单的远程调用,我感觉还是用 http 吧,想提升性能可以用 http2 ?毕竟 grpc 也是基于 http2 的
    Maboroshii
        10
    Maboroshii  
       2025 年 2 月 27 日
    顺带 protobuf 最大优势也就是性能上,多项目、多人维护的时候,工作流程上也是脑袋都大了。
    cj323
        11
    cj323  
       2025 年 2 月 27 日 via iPhone
    不好用是因为没有人用 TS/python 搭配 grpc 。gprc 主要就是提升传输效率,但你传输层提升半天最后应用层进 node/v8 这种运行时又会变很慢。就像开 F1 下午五点去东三环一样,意义微乎其微。
    Vegetable
        12
    Vegetable  
       2025 年 2 月 27 日
    grpc 的易用性从来就没好过吧,用它团队里总得有几个人头疼。

    其实 jsonschema 在两边都能找到可用的生成器,我觉得好于 grpc
    minami
        13
    minami  
       2025 年 2 月 27 日
    1 、protobuf 本身就很糟糕,如果你不是谷歌那种全公司代码在一个仓库里的管理方式,建议别用
    2 、绝大部分的 RPC 需求用 JSON-RPC 就能满足,性能瓶颈根本不在 RPC 库上
    xuanbg
        14
    xuanbg  
       2025 年 2 月 28 日
    你一边接口的参数/返回数据的结构变了,用什么 rpc 协议都不能让你不用改调用者的逻辑就能实现同步啊。
    superhot
        15
    superhot  
    OP
       2025 年 2 月 28 日
    感谢各位的解答,我再去看看 json schema
    renyijiu
        16
    renyijiu  
       2025 年 2 月 28 日
    用 connectrpc 支持 grpc, buf 算是 proto 这块很好用的工具了, https://buf.build/explore
    superhot
        17
    superhot  
    OP
       2025 年 2 月 28 日
    @renyijiu 这个我也看了,好像只支持 TS 做客户端发 gPRC 请求,做不了服务端?如此的话 Python 那块还是没法解决
    renyijiu
        18
    renyijiu  
       2025 年 2 月 28 日
    @superhot #17 https://connectrpc.com/docs/node/getting-started node 版本不是可以作为 server 吗?当然我对 js 很了解
    yzld2002
        19
    yzld2002  
       2025 年 2 月 28 日
    一样的用法,看了下我 ts 这边用的是 grpc_tools_node_protoc_plugin ,生成的代码没动过就可以带 type
    反倒是 python 这边生成的代码过不了 lint ,而且 import 确实有问题,得自己手改一下
    HappyAndSmile
        20
    HappyAndSmile  
       2025 年 2 月 28 日
    不是吧,不理解楼上的人的说法,即使 protobuf ,gRPC 不好用,也总能用吧,不至于用不到吧?另外,每次改动后,生成一大片 diff? 是有 diff ,也没多大啊
    iflint
        21
    iflint  
       2025 年 2 月 28 日
    ts 里面用 GRPC 确实比较难受。之前做出过 ts 服务端和 Android (kt) 客户端的通信,kt 里面有明确的接入步骤和官方的插件生成产物。ts 的话也有不少插件但是能很舒服用的不多。目前在用的是 grpc_tools_node_protoc_ts 、ts-proto 、ts-protoc-gen 这几个。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   1074 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 23:39 · PVG 07:39 · LAX 15:39 · JFK 18:39
    ♥ Do have faith in what you're doing.