gRPC 对比 WebSocket

gRPC

gRPC 是一个远程过程调用框架,默认使用 protobuf3 进行数据的高效序列化与 service 定义,使用 HTTP/2 进行数据传输。 这里讨论的是 gRPC over HTTP/2 协议。

目前 gRPC 主要被用在微服务通信中,但是因为其优越的性能,它也很契合游戏、loT 等需要高性能低延迟的场景。

其实从协议先进程度上讲,gRPC 基本全面超越 REST:

  1. 使用二进制进行数据序列化,比 json 更节约流量、序列化与反序列化也更快。
  2. protobuf3 要求 api 被完全清晰的定义好,而 REST api 只能靠程序员自觉定义。
  3. gRPC 官方就支持从 api 定义生成代码,而 REST api 需要借助 openapi-codegen 等第三方工具。
  4. 支持 4 种通信模式:一对一(unary)、客户端流、服务端流、双端流。更灵活

只是 目前 gRPC 对 broswer 的支持仍然不是很好,如果你需要通过浏览器访问 api,那 gRPC 可能不是你的菜。 如果你的产品只打算面向 App 等可控的客户端,可以考虑上 gRPC。

对同时需要为浏览器和 APP 提供服务应用而言,也可以考虑 APP 使用 gRPC 协议,而浏览器使用 API 网关提供的 HTTP 接口,在 API 网关上进行 HTTP - gRPC 协议转换。

gRPC over HTTP/2 定义

详细的定义参见官方文档 gRPC over HTTP/2 .

这里是简要说明几点:

  1. gRPC 完全隐藏了 HTTP/2 本身的 method、headers、path 等语义,这些信息对用户而言完全不可见了。
    请求统一使用 POST,响应状态统一为 200。只要响应是标准的 gRPC 格式,响应中的 HTTP 状态码将被完全忽略。
  2. gRPC 定义了自己的 status 状态码、格式固定的 path、还有它自己的 headers。

WebSocket

WebSocket 是一个双向通信协议,它在握手阶段采用 HTTP/1.1 协议(暂时不支持 HTTP/2)。

握手过程如下:

  1. 首先客户端向服务端发起一个特殊的 HTTP 请求,其消息头如下:
1
2
3
4
5
6
7
8
GET /chat HTTP/1.1  // 请求行
Host: server.example.com
Upgrade: websocket // required
Connection: Upgrade // required
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // required,一个 16bits 编码得到的 base64 串
Origin: http://example.com // 用于防止未认证的跨域脚本使用浏览器 websocket api 与服务端进行通信
Sec-WebSocket-Protocol: chat, superchat // optional, 子协议协商字段
Sec-WebSocket-Version: 13
  1. 如果服务端支持该版本的 WebSocket,会返回 101 响应,响应标头如下:
1
2
3
4
5
HTTP/1.1 101 Switching Protocols  // 状态行
Upgrade: websocket // required
Connection: Upgrade // required
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // required,加密后的 Sec-WebSocket-Key
Sec-WebSocket-Protocol: chat // 表明选择的子协议

握手完成后,接下来的 TCP 数据包就都是 WebSocket 协议的帧了。

可以看到,这里的握手不是 TCP 的握手,而是在 TCP 连接内部,从 HTTP/1.1 upgrade 到 WebSocket 的握手。

WebSocket 提供两种协议:不加密的 ws:// 和 加密的 wss://. 因为是用 HTTP 握手,它和 HTTP 使用同样的端口:ws 是 80(HTTP),wss 是 443(HTTPS)

对比

gRPC 实际上并不是比较的相关部分,而是 gRPC 使用 的 HTTP/2 与 WebSockets 进行比较。这里借鉴 InfoQ 上的一篇文章 WebSocket 能否在 HTTP/2 中存活下来?

虽然 HTTP/2 提供了很多机制,它并不能完全取代现有的推/流媒体技术的需要。

关于 HTTP/2 的第一个重要的事情是它并不能替代所有的 HTTP 。verb、状态码和大部分头信息将保持与目前版本一致。HTTP/2 是意在提升数据在线路上传输的效率。

比较 HTTP/2 和 WebSocket ,可以看到很多类似之处:

- HTTP/2 WebSocket
Headers Compressed (HPACK) None
Binary Yes Binary or Textual
Multiplexing Yes Yes
Prioritization Yes No
Compression Yes Yes
Direction CLient/Server + Server Push Bidirectional
Full-duplex Yes Yes

如何选择

WebSockets 肯定会在 HTTP/2 + SSE 的领域中生存下来,主要是因为它是一种已经被很好地应用的技术,并且在非常具体的使用情况下,它比 HTTP/2 更具优势,因为它已经被构建用于具有较少开销(如报头)的双向功能。

假设你想建立一个大型多人在线游戏,需要来自连接两端的大量消息。在这种情况下,WebSockets 的性能会好很多。

一般情况下,只要需要客户端和服务器之间的真正 低延迟 ,接近实时的连接,就使用 WebSocket 。请记住,这可能需要重新考虑如何构建服务器端应用程序,以及将焦点转移到队列事件等技术上。

如果你使用的方案需要显示实时的市场消息,市场数据,聊天应用程序等,依靠 HTTP/2 + SSE 将为你提供高效的双向通信渠道,同时获得留在 HTTP 领域的各种好处:

当考虑到与现有 Web 基础设施的兼容性时,WebSocket 通常会变成一个痛苦的源头,因为它将 HTTP 连接升级到完全不同于 HTTP 的协议。

规模和安全性:Web 组件(防火墙,入侵检测,负载均衡)是以 HTTP 为基础构建,维护和配置的,这是大型/关键应用程序在弹性,安全性和可伸缩性方面更喜欢的环境。

----------本文结束感谢您的阅读----------
xiaolong wechat
一只程序猿对世界的不完全理解