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

74 阅读2分钟

走进HTTP协议

HTTP协议是什么

  • HTTP 是超文本传输协议(Hypertext TransferProtocol)
  • 可以了解都安排:1.信息明确的边界 2.能够携带什么类型的信息

协议里面有什么

图片.png

请求流程

图片.png

不足与展望

  • HTTP1
  1. 队头阻塞
  2. 传输效率低
  3. 明文传输不安全
  • HTTP2
  1. 多路复用
  2. 头部压缩
  3. 二进制协议
  • QUIC
  1. 基于UDP实现
  2. 解决队头阻塞
  3. 加密减少握手次数
  4. 支持快速启动

HTTP框架的设计与实现

分层设计

图片.png

  1. 高内聚低耦合
  2. 易复用
  3. 高扩展性

图片.png

应用层设计

提供合理的 API

  • 可理解性:如 ctx.Body(),ctx.GetBody()
    不要用 ctx.BodyA()
  • 简单性:如 ctx.Request.Header.Peek (key)
    /ctx. GetHeader (key)

中间件设计

中间件需求:

  1. 配合 Handler 实现一个完整的请求处理生命周期
  2. 拥有预处理逻辑与后处理逻辑
  3. 可以注册多中间件
  4. 对上层模块用户逻辑模块易用

洋葱模型

核心逻辑与通用逻辑分离

图片.png

  1. 既然要实现预处理和后处理,那这个就很像调用了一个函数
func Middleware (some param) {
    // some logic for pre-handle
    ...
    Next( )
    //some Logic for after-handle
    ...
}
  1. 路由上可以注册多 Middleware,同时也可以满足请求级别有效,只需要将 Middleware 设计为和业务和 Handler 相同即可。
  2. 用户如果不主动调用下一个处理函数怎么办?
    核心:在任何场景下Index保证递增
  3. 出现异常想停止怎么办?
func (ctx *RequestContext) Abort(){
    ctx.index = IndexMax  //直接将Index设置为最大值
}

调用链:
图中调用链存在一个问题:不在同一调用栈上

图片.png 适用场景

  • 不调用 Next: 初始化逻辑且不需要在同一调用栈
  • 调用 Next: 后处理逻辑或需要在 同一调用栈上

路由设计

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

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

路由设计的最佳方案

前缀匹配树:

图片.png

如何匹配HTTP方法

图片.png

总结

  • AP设计:可理解性、简单性...
  • 中间件设计:洋葱模型
  • 路由设计:前缀匹配树
  • 协议层设计:抽象出合适的接口
  • 网络层设计: 网络模型