【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

  • A+
所属分类:golang

1. 前言

学习了前文【Golang | gRPC】使用gRPC实现简单远程调用,后面开始了解gRPC的流模式,分为三种:

  • 客户端流
  • 服务端流
  • 双向流

那什么是流,在谈流的概念前,有必要先简单了解下HTTP的连接管理经历了哪些演变。

2. HTTP连接

HTTP连接其实就是TCP连接及其使用规则。一旦建立了TCP连接后,客户端开始发送HTTP请求,而服务端读取请求,当读取完整条请求报文后,就会对请求进行处理,执行所请求的动作,然后将数据写回客户端。最后客户端读取数据,并对响应数据进行处理。
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

3. HTTP连接管理

3.1 串行连接(短连接)

如果对HTTP连接只进行简单的管理,当HTTP事务串行加载时,TCP的连接时延就会叠加起来,如下图:
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

3.2 并行连接

通过多条TCP连接发起并发的HTTP请求,克服单条连接的空载时间和带宽限制。但是并行连接会导致服务端打开大量连接从而消耗内存资源,引发性能问题
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

3.3 持久连接(长连接)

重用TCP连接,以消除连接及关闭时延。HTTP/1.1(包括HTTP/1.0的各种增强版本)允许事务处理结束后保持TCP连接处于打开状态
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

3.4 管道化连接

无论是串行连接还是持久连接,HTTP报文都遵循一发一收的流程,HTTP/1.1引入的管道化连接允许将多条请求放入队列,依次发送,服务端按照与请求相同的顺序回送HTTP响应(这种机制可能导致队首阻塞问题,即如果服务端的某一个请求处理耗时过久,会导致后面请求对应的响应阻塞,不能发送给客户端)
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

3.5 HTTP/2.0中的流(stream)

不同HTTP/1.0协议,HTTP/2.0在TCP层(或者TLS层,如果有)和HTTP层之间添加一层二进制分帧层(Binary Framing Layer),将HTTP报文分为更小的Headers帧(对应HTTP/1.0报文的起始行和首部)和DATA帧(对应HTTP/1.0报文主体部分),然后进行二进制编码发送给对端
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

要理解这样的二进制分帧机制,首先要理解几个概念:stream(流)、message(消息)frame(帧)

  • stream是一条抽象意义的双向字节流,建立在TCP连接之上。一条TCP连接可以有多条stream,每条stream可以传输一个或者多个message
  • message可以类比HTTP/1.0协议的一条请求报文(或者响应报文),由frame组成(Headers FrameDATA Frame,通过Type字段标识)。属于同一个message的帧必须要按指定顺序发送,然后到对端按照Stream Identifier(流标志符)进行组合,多个message的帧可以交错发送
  • frame是HTTP/2.0的最小通信单元,通过Flags可以标志流的结束

如下是一个HTTP/2.0帧格式和gRPC报文格式
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进
【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

整个基于HTTP/2.0协议的网络通信可以简单理解为:先建立TCP连接,然后是HTTP/2.0协议的一些初始化通信(比如SETTING帧)。之后客户端将message拆分成多个frame(HEADERS帧DATA帧),通过stream发送frame,服务端收到后将frame重新组合成message;反之亦然

【Golang | gRPC】HTTP的连接管理——从HTTP/1.0到HTTP/2.0的演进

4. HTTP/2.0与gRPC的流模式

gRPC框架中的C/S通信就是使用的HTTP/2.0协议

HTTP/2.0的优点除了降低了通信时延,另一方面使C/S通信不再局限于HTTP/1.0的一发一收模式,同时有效地解决了HTTP/1.1的管道化连接带来的响应报文队首阻塞问题(注:这里的队首阻塞仅是指HTTP层)

客户端可以发送多个message请求,服务端在获取所有的message请求后返回message响应(对应gRPC中的客户端流模式);客户端发送单个message请求,服务端接收处理后,可以返回多个message响应(对应gRPC中的服务端流模式);客户端也可以每发送一个message请求,服务端接受处理后就返回一个message响应(对应gRPC中的双向流模式)

w3cjava