学习笔记-LEC4-HTTP框架修炼之道 | 青训营

63 阅读10分钟

LEC4-HTTP 框架修炼之道

本文部分图片资料源自《字节内部课》课程学习资料

HTTP 框架修炼之道 .pptx - 飞书云文档 (feishu.cn)

【Go 语言框架与实现 学习资料】字节跳动青训营 - 后端专场 - 掘金

01. 再谈HTTP协议

为什么需要协议0

  1. 明确的边界
  2. 信息解析
  3. (预留拓展)

HTTP最早版本

0.9

HTTP协议的最初版本是HTTP/0.9,它于1991年问世。这个版本非常简单,只支持无格式的文本数据传输,没有请求头、响应头等结构化信息。

HTTP/0.9的主要特点如下:

  1. 请求方式:只支持GET请求方法,即通过GET方法请求服务器上的资源。
  2. URL:只能包含请求的路径,没有主机名、端口号、查询参数等。
  3. 响应格式:服务器返回的响应只包含请求资源的纯文本内容,没有响应头、状态码等。
  4. 连接:每次请求都会关闭连接,无法保持持久连接。
  5. 内容类型:响应的内容类型默认为HTML。

HTTP报文结构

image-20230813230435244

PATCH与PUT

  • PUT:用于向服务器上传资源或更新资源,通常会指定资源的完整内容,如果资源已经存在则进行替换,如果不存在则创建。
  • PATCH:类似于PUT,但是它是对资源进行局部更新,客户端只需提供要修改的部分数据,而不需要提供完整资源。

1.请求报文(Request Message) :

  • 请求行(Request Line) :包含请求方法、请求目标URL和HTTP协议版本。
  • 请求头部(Request Headers) :包含关于请求的附加信息,如User-Agent、 Accept、Content-Type等。
  • 空行(Blank Line) :请求行和请求头部之后是一个空行, 用于分隔请求头部和请求体。
  • 请求体(Request Body) :用于在POST或PUT请求中传输数据。

2.响应报文(Response Message) :

  • 状态行(StatusLine) :包含HTTP协议版本、状态码和状态短语。
  • 响应头部(Response Headers) :包含关于响应的附加信息,如Content-Type、Content-L ength等。
  • 空行(Blank Line) :状态行和响应头部之后是一个空行, 用于分隔响应头部和响应体。
  • 响应体(Response Body) :包含服务器返回的实际数据,如HTML文档、JSON数据等。

请求流程

image-20230813233729356

  1. 业务层:包含业务逻辑和应用程序特定的处理。在这一层,应用程序处理请求,执行业务逻辑,生成响应数据。
  2. 服务治理层(中间件层) :这一层包含各种中间件,用于处理请求的横切关注点,如安全、日志记录、性能监测等。中间件可以在请求进入业务层之前或之后执行一些通用任务。
  3. 路由层:在大多数Web应用中,路由层负责将请求路由到正确的处理程序。它根据请求的URL等信息决定将请求发送到哪个业务逻辑处理模块。
  4. 协议编码层:这一层负责将应用程序数据(响应)编码成符合HTTP协议规范的格式,同时将从客户端接收的HTTP请求解析成应用程序可以处理的数据。这包括HTTP报头的处理、数据的序列化和反序列化等。

不足和展望

image-20230813233710168

队头阻塞:

Head-of-Line blocking, 简写:HOL blocking

因为是基于TCP的,简单讲,就是一个大的或慢的响应会延迟后面的其他响应

传输效率低:头部太大了,内容甚至会比头部还小

02. HTTP框架的设计与实现

分层设计

也采用了分层设计

因为分层设计往往具有复用、高扩展性等特点

五层,相互对应

image-20230817231751855

从上到下

应用层

主要就是要提供合理的API,合理性和简单性

中间件层

一个经典模型:洋葱模型

在 HTTP 框架中,中间件层是一种软件组件,用于处理 HTTP 请求和响应之间的逻辑。中间件提供了一种模块化的方式来处理请求,执行各种任务,以及在请求和响应之间执行一些共享的操作。这使得开发人员能够将应用程序的功能划分为多个可重用的部分,同时保持代码的可读性和可维护性。

中间件可以在请求被处理之前、期间和之后执行,从而允许你对请求和响应进行修改、验证、记录、安全性检查等。一些常见的中间件任务包括:

  1. 身份验证和授权: 中间件可以用来验证用户身份,确保只有授权的用户能够访问某些资源。
  2. 日志记录: 中间件可以记录请求和响应的详细信息,用于调试、监控和分析。
  3. 数据转换: 中间件可以在请求和响应之间进行数据转换,比如将 JSON 数据解析为对象,或将对象转换为 JSON 响应。
  4. 缓存和性能优化: 中间件可以实现缓存策略,以减少服务器负载和提高响应速度。
  5. 安全性: 中间件可以执行安全性检查,如防止跨站脚本攻击(XSS)或跨站请求伪造(CSRF)。
  6. 请求处理流程控制: 中间件可以控制请求的处理流程,例如中断请求、重定向或提前响应。
  7. 错误处理: 中间件可以捕获并处理请求处理过程中的错误,提供自定义的错误响应。
  8. 性能监控和分析: 中间件可以收集请求和响应的性能数据,用于监控和分析系统性能。

基本思想:将请求通过一系列中间件层,每个中间件可以对请求和响应进行处理或修改,然后将请求传递给下一个中间件或处理程序。这种模块化的结构使得开发和维护复杂的 Web 应用程序变得更加容易。

路由设计

框架路由实际上就是为URL匹配对应的处理函数(Handlers)

  • 静态路由: /a/b/c、 /a/b/d
  • 参数路由: /a/:id/c (/a/b/c, /a/d/c)、 /*alI
  • 路由修复: /a/b <-> /a/b/
  • 冲突路由以及优先级: /a/b、 /:id/c
  • 匹配HTTP方法
  • 多处理函数:方便添加中间件

使用前缀树匹配路由

image-20230817235616274

使用map融合到前缀树种实现匹配方法

因为方法是固定的几种,每个有的方法下面挂一棵树,没有树的说明没这个方法,比较好解决

协议编解码层

简单来说其实应该是做了一下解析,对Header等东西进行解析

发过来的是Byte数组,然后要解析内容出来,大概是这样的(针对不同的协议:http1,http2,QUIC等等

网络层(transport设计

注意这里的网络层、transport和OSI七层模型不是一个概念 HTTP 框架的网络层通常被称为 "transport",它在框架中的角色是负责处理底层的网络通信,数据传输和连接管理。这一层提供了一个抽象接口,用于处理不同的传输协议(如 TCP、UDP)和处理数据的收发。

这里解释一下为什么网络层通常称为 "transport",以及它在 HTTP 框架中的具体作用:

  1. 抽象不同传输协议: HTTP 是基于 TCP 协议的应用层协议,但是在实际网络编程中,可能还会涉及到其他传输协议,如 UDP、WebSocket 等。"Transport" 这个术语更抽象,可以用于表示处理不同传输协议的通用性。
  2. 连接管理: 在网络通信中,建立和管理连接是一个重要的任务。"Transport" 层负责管理这些连接,包括建立、维护和关闭连接。
  3. 数据传输: HTTP 框架的 "transport" 层负责将数据从客户端发送到服务器,以及从服务器发送响应到客户端。这包括了数据的拆分、打包、传输、接收和组装等操作。
  4. 事件驱动: "Transport" 层通常是基于事件驱动的,这意味着它会监听网络事件,如新连接的到来、数据可读、数据可写等。在收到事件后,它会调用适当的逻辑来处理事件。
  5. 异步处理: 许多现代的 HTTP 框架使用异步模型来处理网络通信,以提高性能和并发处理能力。"Transport" 层可以负责实现异步操作,从而允许同时处理多个连接和数据传输。

总之,"transport" 层在 HTTP 框架中扮演了一个关键的角色,它处理底层的网络通信细节,允许开发者更专注于处理应用层逻辑。这种抽象层级使得 HTTP 框架更具灵活性,能够适应不同的网络环境和需求。

两种设计BIO与NIO

BIO(阻塞 I/O)设计

在使用阻塞 I/O 模型的网络层中,每个客户端连接都会创建一个独立的线程来处理。当有请求到达时,服务器线程会阻塞在 I/O 操作上,直到数据读取完毕或响应发送完成。这种模型的特点包括:

  • 简单直观: 每个连接都对应一个线程,编程模型相对简单,易于理解和实现。
  • 易于调试: 可以轻松地在每个线程中进行调试,更容易发现问题。
  • 适用于低并发: 适用于连接数量较少的情况,如小型应用、测试环境等。

然而,BIO 模型也有其缺点:

  • 资源占用高: 创建大量线程来处理连接会占用大量系统资源,限制了并发连接的数量。
  • 性能有限: 在高并发环境下,由于线程切换和管理开销,性能可能受到限制。
  • 可扩展性差: 随着连接数量的增加,线程管理和调度变得复杂,可扩展性较差。

NIO(非阻塞 I/O)设计

在使用非阻塞 I/O 模型的网络层中,只需少量的线程来处理大量连接。这些线程使用非阻塞方式处理数据读写,通过选择器来监视多个通道的状态。这种模型的特点包括:

  • 高并发性: 只需少量线程即可处理大量连接,提高了并发性能。
  • 资源占用较少: 线程数量较少,占用较少系统资源。
  • 适用于高并发: 适用于需要处理大量连接的情况,如 Web 服务器、代理服务器等。

然而,NIO 模型也有其复杂性:

  • 编程复杂: 需要处理非阻塞读写,需要编写更复杂的代码逻辑。
  • 可维护性降低: 随着连接数量的增加,需要更多的编码和设计工作来管理连接。

选择适用场景:

  • 如果你的 HTTP 框架主要面向低并发环境或者开发者对并发性能要求不高,BIO 可能是一个相对简单的选择。
  • 如果你的 HTTP 框架需要处理大量并发连接且对性能有较高要求,NIO 可以更好地满足这些需求。