gRPC
gRPC 是一个远程过程调用框架,默认使用 protobuf3 进行数据的高效序列化与 service 定义,使用 HTTP/2 进行数据传输。 这里讨论的是 gRPC over HTTP/2 协议。
目前 gRPC 主要被用在微服务通信中,但是因为其优越的性能,它也很契合游戏、loT 等需要高性能低延迟的场景。
其实从协议先进程度上讲,gRPC 基本全面超越 REST:
- 使用二进制进行数据序列化,比 json 更节约流量、序列化与反序列化也更快。
- protobuf3 要求 api 被完全清晰的定义好,而 REST api 只能靠程序员自觉定义。
- gRPC 官方就支持从 api 定义生成代码,而 REST api 需要借助 openapi-codegen 等第三方工具。
- 支持 4 种通信模式:一对一(unary)、客户端流、服务端流、双端流。更灵活
只是 目前 gRPC 对 broswer 的支持仍然不是很好,如果你需要通过浏览器访问 api,那 gRPC 可能不是你的菜。 如果你的产品只打算面向 App 等可控的客户端,可以考虑上 gRPC。
对同时需要为浏览器和 APP 提供服务应用而言,也可以考虑 APP 使用 gRPC 协议,而浏览器使用 API 网关提供的 HTTP 接口,在 API 网关上进行 HTTP - gRPC 协议转换。
gRPC over HTTP/2 定义
详细的定义参见官方文档 gRPC over HTTP/2 .
这里是简要说明几点:
- gRPC 完全隐藏了 HTTP/2 本身的 method、headers、path 等语义,这些信息对用户而言完全不可见了。
请求统一使用 POST,响应状态统一为 200。只要响应是标准的 gRPC 格式,响应中的 HTTP 状态码将被完全忽略。 - gRPC 定义了自己的 status 状态码、格式固定的 path、还有它自己的 headers。
WebSocket
WebSocket 是一个双向通信协议,它在握手阶段采用 HTTP/1.1 协议(暂时不支持 HTTP/2)。
握手过程如下:
- 首先客户端向服务端发起一个特殊的 HTTP 请求,其消息头如下:
1 | GET /chat HTTP/1.1 // 请求行 |
- 如果服务端支持该版本的 WebSocket,会返回 101 响应,响应标头如下:
1 | HTTP/1.1 101 Switching Protocols // 状态行 |
握手完成后,接下来的 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 为基础构建,维护和配置的,这是大型/关键应用程序在弹性,安全性和可伸缩性方面更喜欢的环境。