HTTP协议即超文本传输协议,作为当今使用最广泛的协议之一,是客户端与服务器端通信的基础协议,前后端分离的情况下可以通过HTTP请求进行通信。而HTTP框架负责对HTTP请求的解析,根据对应路由选择对应的后端逻辑。
本文图片资料出自《字节内部课》中HTTP框架修炼之道的文档。
一、HTTP协议
1.1 HTTP协议介绍
HTTP协议包括请求报文和响应报文两种:
请求报文
- 请求行:含有方法名(例如GET、POST等),URL,协议版本
- 请求头:包括协议约定和相关业务等
- 请求体:在POST或PUT请求中传输数据
响应报文
- 状态行:含有协议版本、状态码和对状态码的描述,状态码有信息类,重定向,客户端错误等多种类型
- 响应头:包括协议约定和相关业务等
- 响应体:服务器返回的实际数据,例如JSON数据。
详情可参看下图
1.2 请求流程
一次完整的请求如下图所示,分别有业务层、服务治理层、中间件层、路由层、协议编码或协议解码层、传输层。
首先,业务层中应用程序处理请求,使用API完成业务逻辑,生成响应数据。
其次,进入服务治理层,该层依托于中间件层,对每个请求做出一些先处理或后处理的判断,可以进行日志记录、性能检测等。
然后,在协议编码层中,将负责将应用程序数据编码,即将报文编译成能识别的内容,进行数据的序列化和反序列化等。
最后,将处理后的信息到传输层进行传输。
对于服务器端,传输层到业务层的过程中,路由层可以根据URL选择对应的业务处理的模块,找到正确的处理程序。
1.3 HTTP的不足
- http1:基于TCP协议,会伴随着队头阻塞的问题,传输效率低,明文传输不安全。
- http2:解决了http1的部分问题,进行多路复用,头部压缩,使用二进制协议解析更高效,但仍然基于TCP协议,没有解决队头阻塞的问题。
- QUIC:基于UDP实现,相比于http1和http2解决了队头阻塞的问题,减少了握手次数,支持快速启动。
二、HTTP框架
2.1 分层设计
HTTP框架采用分层设计,可以让不同层同一时间完成不同工作,只需要考虑下一层给上一层的接口,特定层的人进行该层的开发即可。分层设计带来了专注性、扩展性、复用性的提高,其分层设计如下:
- 应用层:应用层直接与用户打交道,提供一些常用的API接口。
- 中间件层:用于处理HTTP请求和响应之间的逻辑,具有预处理逻辑和后处理逻辑,适用于日志记录、性能统计、安全控制等
- 路由层:实现类似于注册,寻址等操作,能为URL匹配对应的处理的函数。
- 协议层:对当前数据进行处理,利用HTTP2,QUIC进行解析。
- 网络层:处理底层的网络通信,数据传输和连接管理,在网络层将处理数据的收发。
2.2 BIO与NIO
2.2.1 BIO
左边代码为block io,简称bio。listener每次accept获取连接之后开启一个goroutine,在该线程中利用Read读取数据,处理之后再用Write写回。
BIO方式是一种阻塞I/O模型的设计,每个请求到达时,线程阻塞在I/O操作上,例如假如读取到一半的话,无法去做其他的工作,而需要等待数据读取完毕或响应发送完成。
bio设计简单直观,适用于低并发的情况,例如小型应用或是测试环境,更易于调试,但资源占用高,在高并发的环境下性能有限,连接数量的增加会使线程调度变得复杂。
2.2.2 NIO
右边代码为non block io,简称nio,是一种非阻塞的方式。每次获取连接后将该连接加入一个监听器monitor中,轮询监听器monitor,找到可读的连接,去执行该连接的Read,拿到完整的数据并处理。这就相当于当一个数据只有一半时,可以让它先去读取其他连接,直到这个包已经发完,再回来对这边的数据进行读取。
NIO方式具有高并发性,占用的资源较少,适用于处理大量连接的情况。但是该模型需要处理非阻塞读写,编程复杂,可维护性降低。
- 当HTTP框架仅用于平时小型的开发,面向低并发环境或针对平时的测试,使用BIO方式有好处。
- 当HTTP框架用于大型工程的开发,具有大量的连接和处理需求,使用NIO方式更合适。