V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drymonfidelia
V2EX  ›  程序员

gRPC 和普通 HTTP API 哪个更适合 APP 客户端与服务器通信?为什么大部分 APP 都还在使用传统 HTTP API?

  •  
  •   drymonfidelia · 40 天前 · 4787 次点击
    这是一个创建于 40 天前的主题,其中的信息可能已经有所发展或是发生改变。
    68 条回复    2024-11-14 11:34:26 +08:00
    hefish
        1
    hefish  
       40 天前
    因为大部分 app 开发是 sb ,只有用 grpc 的才是正常开发。
    我也是 sb 。
    kk2syc
        2
    kk2syc  
       40 天前   ❤️ 4
    因为大部分 APP 用不到 gRPC 带来的性能提升,反而提高了因为开发维护的难度。都是草台班子,规范的 http-api 就不错了,更别提还有用纯 text 做接口的。(只返回 OK 、ERROR 字符串)
    tool2dx
        3
    tool2dx  
       40 天前 via Android   ❤️ 1
    gRPC 对比来说,和 json 或者 xml 都不一样,不是自解释的,必须要搭配着 protocol 文件一起用,就挺麻烦的。
    也有可能是大部分开发项目,都在实现功能阶段,远远没有达到优化阶段。
    flyqie
        4
    flyqie  
       40 天前 via Android   ❤️ 3
    其实我更想问你为什么会觉得应该用 grpc 而不是 http?
    fpk5
        5
    fpk5  
       40 天前
    grpc 是二进制的,可能在调试的时候比较麻烦?
    louiswong2099
        6
    louiswong2099  
       40 天前
    grpc 还没有 http api 应用的那么广泛,但是可以在服务器内部之前大量使用。
    drymonfidelia
        7
    drymonfidelia  
    OP
       40 天前
    @flyqie HTTP2 可以复用连接,结合 protobuf 压缩效率高提升弱网体验,传输的是二进制没有编码问题,还可以直接把图片和文字一起传输不用 base64 浪费带宽
    akira
        8
    akira  
       40 天前
    你缺这点带宽么。。
    wangritian
        9
    wangritian  
       40 天前
    传统 api 也可以 h2
    你会问这个问题肯定也用不到 protobuf 对比 json 的提升
    你非要图片文字一起传?更不用说对象存储
    唯一考虑点就是你要不要服务器主动推数据,一般也是走系统推送
    drymonfidelia
        10
    drymonfidelia  
    OP
       39 天前
    @akira 弱网环境下少传 1kb 都能提升体验
    fox0001
        11
    fox0001  
       39 天前 via Android   ❤️ 1
    一般使用 http 。主要是因为 grpc 是保持连接的,服务器的连接数是有限制的,使用 grpc 会导致限制了客户端数量。

    重点还是根据实际情况而定。
    RightHand
        12
    RightHand  
       39 天前 via Android
    要保持长连接,弱网不行,闪断不行。为什么要用这个 xx 玩意
    musi
        13
    musi  
       39 天前 via iPhone   ❤️ 12
    @drymonfidelia #7
    “HTTP2 可以复用连接”
    你都说是 HTTP2 了,http api 用不了吗?

    “结合 protobuf 压缩效率高提升弱网体验”
    protobuf 的压缩效率比 gzip 高多少你测试过吗?

    “还可以直接把图片和文字一起传输不用 base64 浪费带宽”
    你到底是想省带宽还是浪费带宽?但凡考虑点体验和带宽都会选择把图片放 cdn 吧
    tyc
        14
    tyc  
       39 天前
    @louiswong2099 突破我认知了,我一直了解的都是在服务器内部大量使用的是 RPC
    SmiteChow
        15
    SmiteChow  
       39 天前   ❤️ 3
    有没有可能 grpc 底层其实是 http ?
    hxzhouh1
        16
    hxzhouh1  
       39 天前
    Grpc 没有你想的那么好, 取代不了 HTTP ,为什么会有 GRPC-WEB 这个项目?
    https://kmcd.dev/posts/grpc-the-bad-parts/

    https://taoshu.in/grpc-trailers.html
    unco020511
        17
    unco020511  
       39 天前
    http 不是一样可以用 protobuf 吗
    duduke
        19
    duduke  
       39 天前 via iPhone
    单链接在弱网下,智障得很,所有请求全部阻塞
    sunny352787
        20
    sunny352787  
       39 天前
    用 http 一个是开发方便,不用配置协议文件直接处理 json 就好,另一个是对于目前的云服务提供商来说,http 的支持比 grpc 好很多,包括负载均衡、DDOS 防御、流量清洗等
    lambdaq
        21
    lambdaq  
       39 天前
    这什么沙雕问题。我来给你个沙雕回答吧。最适合的是用 h2 传输 pb ,然后 pb 就定义一个 string 字段用来传 json 字符串。
    kw8023cn
        22
    kw8023cn  
       39 天前
    @drymonfidelia #10 如果你的目标用户,地理位置都是山区的话,那确实可以考虑
    tbxark
        23
    tbxark  
       39 天前
    http 方便抓包调试,方便给 web 和小程序服务。grpc 还是适合微服务之间通信。
    f7014367google
        24
    f7014367google  
       39 天前
    如果有服务需要扩容,请问阁下该怎么使用 gRPC 进行负载均衡呢?
    willchen
        25
    willchen  
       39 天前
    @f7014367google 这不是问题吧 nginx 也早支持了
    julyclyde
        26
    julyclyde  
       39 天前
    @drymonfidelia 客户都弱网了,还有啥价值啊……

    以及,为啥要 base64 ? http 难道不支持 binary 么?
    julyclyde
        27
    julyclyde  
       39 天前
    @lambdaq 我还以为用 json 代替 pb 作为编码层呢……你这个太狠了
    lambdaq
        28
    lambdaq  
       39 天前
    @julyclyde 然后把 图片 base64 到 json 里传输~
    minoic
        29
    minoic  
       39 天前 via Android
    @hxzhouh1 grpc-web 是为了适配浏览器环境,其实约等于是 grpc-js ,支持各种工作环境反而更方便它替代一些 http 场景。
    jeesk
        30
    jeesk  
       39 天前
    @kk2syc 扯淡想要性能还玩 grpc ?
    kaf
        31
    kaf  
       39 天前
    grpc 基于 http2 封装的,而且现在 http2 基本也普及了,直接用 http2 也没什么差别啊,更不要说满大街前端一辈子都是写 json
    sampeng
        32
    sampeng  
       39 天前
    你可以不用啊。又没人强迫你。你去怼你同事和老大去啊。。。
    hxzhouh1
        33
    hxzhouh1  
       39 天前
    @minoic 所以咯,GRPC 是有缺陷的,需要一些其他组件来支持。
    inhzus
        34
    inhzus  
       39 天前
    前司用的就是类似的协议,性能有提升吗:客户端几乎没有,接入层的提升很大。弱网环境相较竞品,快,真的快
    大部分 App 有这个必要吗?没必要。
    guoooo00oohao
        35
    guoooo00oohao  
       39 天前
    还是要看场景,大部分情况下 http 就够用了,生态成熟比如开发,调试,debug ,生产环境的网关,trace 都有很多现成的方案。

    grpc 有 encoding 虽然大部分情况下性能比 http 要好一些,但是不容易 debug 。
    kk2syc
        36
    kk2syc  
       39 天前
    @jeesk 扯淡的说就是提升性能,当然你也可以自己搞一套所谓的压缩复用
    f7014367google
        37
    f7014367google  
       39 天前
    @willchen 这不就是"又"引入了额外的组件吗?比如跑在 k8s 上的微服务,用了 gRPC ,"又"需要额外引入一个"nginx ingress"。
    KiraMaple
        38
    KiraMaple  
       39 天前
    我个人认为 gRPC 的着重点是 RPC 上,可以在微服务/CS 之间像调用本地函数一样调用其他服务的函数,这能极大提升开发效率,但也需要通信的双方协议对齐,这是 RPC 的特点。因为 gRPC 最终打包接口采用的 protobuf ,一个非常优秀的序列化反序列化方案,这能带来更低的流量和更好的性能。也因为采用了 protobuf ,让浏览器上开发调试的时候变得更加复杂,比如 xml/json 那么清晰。不过 protobuf 带来的好处其实 i 也可以依托其他高效的序列化方案来处理。不过 gRPC 很多特性是依托较新浏览器特性才能支持的,所以它对浏览器的支持有一定要求。
    相反在微服务之间的场景几乎没有上述所说的诸多缺点,所以现阶段 gRPC 更多还是用在微服务之间的调用或者 BS 模型的产品。
    skipper1314
        39
    skipper1314  
       39 天前
    1 、还是 HTTP 更普及,而且不容易被 QOS
    2 、HTTP 调试抓包和分析比 gRPC 更方便
    3 、gRPC 确实有很多优化,高效的全双工流式传输等等。但是,就像可读性相比性能,肯定可读性和易用性更优先。
    jeesk
        40
    jeesk  
       39 天前
    @KiraMaple grpc 和浏览器有啥关系? 不过 gRPC 很多特性是依托较新浏览器特性才能支持的 ?
    sampeng
        41
    sampeng  
       39 天前
    这是技术问题么?你先说服你同事吧
    joyypjh
        42
    joyypjh  
       39 天前
    弱网情况下 gRPC 很炸裂,没有细究原因,直接绕坑走
    guanzhangzhang
        43
    guanzhangzhang  
       39 天前
    主要是很多业务的量不是很大,导致对性能追求不大
    其次世界都是草台班子,开发人员大多是 curd , 只会 http 这种更广泛的,消息协议最广泛的就是 json 了。

    我们组的前后端都会写的开发,连 protobuf 都不知道。。。反倒是那些自己接项目的全栈开发基本都知道。然后我看他负责的项目有用到 websocket ,我就好奇用 json 的话,websocket 没有 http url 路由概念,不同结构的消息类型怎么处理的,他说开多个 websocket 连接,每个连接 websocket server 一个 url 建立一种 json 格式 ,我说得亏你没有写 web 游戏开发,不然各种不同的消息类型,每个用户开 100 个 websocket 链接吗
    chaleaochexist
        44
    chaleaochexist  
       39 天前
    @KiraMaple
    "像调用本地函数一样调用其他服务的函数"
    请教, GRPC 提供了哪个 api 哪个 功能 让他调用其他服务的函数像是在调用本地函数?
    http 为什么不能?
    julyclyde
        45
    julyclyde  
       39 天前
    @tool2dx 我其实很担心,proto 文件暴露给前端,被客户下载走,万一其中不怀好意的客户想要分析接口,proto 文件就有点过于详尽了
    beaspiring
        46
    beaspiring  
       39 天前
    你的问题更应该是 gRPC vs REST API, 而不是 gRPC vs HTTP API

    gRPC 的好处:
    1. 类型安全,调用的参数和 method 本身都是,不可能搞错
    2. 支持输入和输出参数的 version ,比如加一个新字段
    3. 网络传输需要的带宽小,client/server 的数据解析更快

    REST AP 用的人更多,理由估计是(从大到小):
    1. 出来更早,更普及
    2. 更容易学和用
    3. 用 gRPC 的好处不明显
    kiracyan
        47
    kiracyan  
       39 天前
    不是一个应用场景
    tojike
        48
    tojike  
       39 天前
    我们是草台班子,不怕你们笑话,我们服务器内网也用的 http
    Jinnrry
        49
    Jinnrry  
       39 天前   ❤️ 3
    @tojike 我也不怕你笑话,我们服务器内网,用 grpc 的人离职以后,其他人接手,立马换成 http
    julyclyde
        50
    julyclyde  
       39 天前
    @Jinnrry http 好歹有个 curl ; grpc 要做客户端还得先弄个 proto 文件,或者开 discovery……
    grzhan
        51
    grzhan  
       39 天前
    感觉大的可能的收益是在二进制序列化协议( protobuf ),一般外部接口感觉是在传输 payload 比较大的时候可能会考虑使用,类似 Prometheus Remote Write API , 一次请求可能是几 MB 或者几十 MB 的写入,Protobuf + Snappy 压缩,也可以像 VictoriaMetrics 使用 zstd 进行压缩,当然传输协议其实还是 HTTP 。

    我不是做移动端的,看了下 Android 的文档也确实有 gRPC 方案的文档介绍( https://developer.android.com/guide/topics/connectivity/grpc ),但也不是主推的样子。加上上面很多老板提到的调试成本、学习门槛,以及弱网下 grpc 可能会存在坑,导致看下来 grpc 在客户端通信通用场景的优势并不明显。
    needhourger
        52
    needhourger  
       39 天前
    @guanzhangzhang websocket 现在也有封装好的 socketio 协议, 可以实现在单个 websocket 上定义专有的事件,以及区分 namespace,类似 http url 的概念。
    wysnxzm
        53
    wysnxzm  
       39 天前
    guanzhangzhang
        54
    guanzhangzhang  
       39 天前
    @needhourger 我知道,同事们这方面知识非常匮乏,说到 socketio ,socketio 社区的 golang 库还是路人写的,而且该库三周之前 archive 了
    Jet
        55
    Jet  
       39 天前
    看着评论区不停跳跃的反问句,其浓度之高,不由自主的乐了起来 😁
    RightHand
        56
    RightHand  
       39 天前 via Android
    补充一点吧,说性能的,性能再好你有 tcp ,udp 强?在 app 中,追求性能那肯定选这两个,追求通用性肯定 http ,grpc 要啥没啥
    jeesk
        57
    jeesk  
       38 天前 via Android
    大部分人以为用了新技术就觉得自己比别人牛了?

    比如大家用 electron , 你用 tarui , 我技术比你牛。

    大家用 http ,你用 protobuf 又觉得比别人牛了。


    反正我会点新技术, 吊吊库, 就是比同事🐂。
    jeesk
        58
    jeesk  
       38 天前 via Android
    因为有时间,你的同事一定会学会 Tauri , 学会 protobuf ,学会 grpc ,那学会了是不是和你一样了?
    fj24911
        59
    fj24911  
       38 天前
    引入 gprc 带来的代码、运维的复杂度,相较 http 的性能提升其实可以忽略不记。
    drymonfidelia
        60
    drymonfidelia  
    OP
       38 天前   ❤️ 1
    @jeesk grpc 难不难用不确定,tauri 是真的垃圾
    drymonfidelia
        61
    drymonfidelia  
    OP
       38 天前
    jeesk
        62
    jeesk  
       38 天前
    首先,大多数应用程序的架构是先有网页,再进行服务器交互,因此大部分接口都是基于 REST HTTP 的设计。为了让 gRPC 支持网页调用,通常需要使用 gRPC-Gateway 或 gRPC-Web 来实现 Web 和 gRPC 协议之间的转换。那么问题来了,为什么谷歌不将所有网页接口设计为使用 gRPC-Web 调用呢?为什么不将文件上传也改为使用 gRPC (这里打个比方,手动狗头,大家自行想象)?

    如果我是架构师,我的项目从一开始就是这样设计的,我是否会直接选择 gRPC ?项目成员是否会对此提出异议?这是否会被视为一种不合理的设计?

    使用 gRPC 带来了哪些好处?

    项目的开发过程往往是先发现问题,再寻找解决方案。

    那么架构师会发现哪些问题?

    1. 双向通信太麻烦, 要么使用 websocket 要么使用 http2, 有没有替代品?
    2. 对多语言适配 sdk 太繁琐了, 能不能为多语言混合直接生成 sdk, 增加请求体的约束减少人力投入文档和 sdk 的编写?
    3. 对性能和带宽以后一定要求



    架构师在这个时候考虑到,Protocol Buffers ( protobuf )作为一种跨平台的交互协议,可以为每种语言生成不同的 schema ,并返回 protobuf 的流式数据。这样,即使使用 HTTP 也能实现高效的交互。谷歌正是看到了这一点,于是基于 protobuf 和 HTTP/2 开发了 gRPC 这一规范性框架。通过 CI 工具为不同平台生成各种语言的 schema ,同时为网页生成通用的库。


    上面这些东西是不是太超前?


    1. 大部分是小企业, 一般就会固定开发语言,不可能出现一家公司 go, java, nodejs, ruby, cpp, python 来相互调用 sdk .
    2. 对外提供的接口太少,小公司可能连文档都没有,都是口头约定。 即是接口多,直接使用 swagger 之类的 openapi 生成一份 http 文档即可,根本不需要投入太多的人力去编写不同语言的文档和 sdk,
    3. 业务也没有双向通信的场景。
    4. 网关使用 gzip 、Zstd 也能够达到节省带宽。

    我就问一问,你是架构师你会怎么选? 没有需求强上需求?
    TORYOI
        63
    TORYOI  
       38 天前
    不要把简单的问题复杂化了
    KiraMaple
        64
    KiraMaple  
       36 天前
    @jeesk #40 gRPC 基于 HTTP2 ,不是所有浏览器都完全支持 HTTP2 的,虽然现在绝大互联网产品都是基于较新的浏览器设计了,但是一些政企部分的客户端系统可能会很老。在更早时候,这个情况更严重,所以 gRPC 在早年更适合服务器之间通信,现在也就形成了路径依赖。
    jeesk
        65
    jeesk  
       36 天前
    @KiraMaple

    grpc 在浏览器使用需要 grpc-web 或者 grpc-gateway , 不支持 http2.0 根本无所谓.
    KiraMaple
        66
    KiraMaple  
       36 天前
    @chaleaochexist gRPC 中的 RPC ,Remote procedure call 翻译作远程过程调用,RPC 概念的提出初衷就是期望像调用本地接口一样远程调用其他服务上的接口。protobuf 作为一个序列化工具,为了支持 gRPC 也支持定义服务和服务中的接口,用来生成调用方的代理调用接口。最开始 gRPC 使用回调的方式达到本地调用的编码体验,但这样容易陷入回调地狱。后来某些编程语言中退出了类似 await/async 等机制,才解决了回调地狱。这样的体验和调用本地接口的编码体验几乎无异,除了你知道这是异步和需要 await 关键字。
    HTTP 经过封装也是可以达到效果的,说到底,gRPC 是基于 HTTP2 结合了 protobuf 、通信、RPC 等功能的一个更上层的 SDK ,如果你是期望达到 RPC 的编码体验,既然有 gRPC 珠玉在前,何必自己用裸 HTTP 再造轮子。
    KiraMaple
        67
    KiraMaple  
       36 天前
    @jeesk #65 那可能我的知识过时了,我接触 grpc 的时候都是好多年前,后面也没有长期使用,当时确实是需要浏览器有 HTTP2 支持
    lizy0329
        68
    lizy0329  
       19 天前
    @SmiteChow 啊哈哈哈,别捅破了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1283 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:02 · PVG 02:02 · LAX 10:02 · JFK 13:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.