HTTP框架设计

66 阅读4分钟

HTTP协议

HTTP协议是什么

  • 超文本传输协议(HyperText Transfer Protocol)

为什么需要协议

  • 需要明确的边界
    • 开始
    • 结束
  • 能够携带信息
    • 什么消息
    • 消息类型

协议里有什么

  • 请求行/状态行
    • 方法名
    • url
    • 协议版本
    • 状态码
    • 状态码描述
  • 请求头/响应头
    • 协议约定
    • 业务相关
  • 请求体/响应体

请求流程

image.png

不足

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

HTTP框架的设计与实现

分层设计

  • 专注性
  • 扩展性
  • 复用性
  • 高内聚
  • 低耦合
  • 易复用
  • 高扩展性

image.png

image.png

image.png

应用层设计

image.png

  • 提供合理的API
    • 可理解性
    • 简单性
    • 冗余性
    • 兼容性
    • 可测性
    • 可见性
    • 别在文档中再进行说明

中间件设计

image.png

  • 需求

    • 配合handler实现一个完整的请求处理生命周期
    • 拥有预处理逻辑和后处理逻辑
    • 可以注册多中间件
    • 对上层模块用户逻辑模块易用
  • 洋葱模型

    • 核心逻辑与通用逻辑分离
    • 适用场景
      • 日志记录
      • 性能统计
      • 安全控制
      • 事务处理
      • 异常处理

image.png

  • 路由上可以注册多middleware,同时也可以满足请求级别有效,只需要将middleware设计为业务和handler相同
  • 在任何场景下index保证递增
  • 调用链
    • 适用场景
      • 不调用Next:初始化逻辑且不需要在同一调用栈
      • 调用Next:后处理逻辑或需要在同一调用栈

image.png

路由设计

image.png

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

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

使用前缀匹配树:

image.png

如何匹配HTTP方法

  • 根据method初步筛选

image.png

如何实现多处理函数 -在每个节点上使用一个list存储handler

如何做设计

  • 明确需求:考虑清楚要解决什么问题
  • 业界调研:业界都有哪些方案可供参考
  • 方案权衡:思考不同方案的取舍
  • 方案评审:相关同学对不同方案做评审
  • 确定开发:确定最合适方案开发

协议层设计

image.png

抽象出合适的接口

  • 不要将上下文存储在结构类型中;而是将上下文显式传递给需要它的每个函数。上下文应该是第一个参数。(Do not store contexts inside a struct type;instead,pass a context explicitly to eachfunction that needs it.The context should be the frist parameter.)
  • 需要在连接上读写数据

网络层设计

image.png

BIO

  • 先读数据再处理,没读完就会卡住

image.png

NIO

  • 等监听器监听到足够的数据才进行唤醒

image.png

总结

HTTP框架设计的核心是HTTP协议。HTTP协议是一种应用层协议,它定义了客户端和服务器之间的通信方式。HTTP框架设计涉及到应用层设计,中间件设计,路由设计,协议层设计和网络层设计。

应用层设计负责处理客户端请求和服务器响应,并且需要考虑到安全性、可扩展性和可维护性等因素。在应用层设计中,我们需要选择合适的编程语言和框架,并且要确保代码的可读性和可维护性。

中间件设计负责在客户端请求和服务器响应之间执行特定的操作,例如身份验证、授权和缓存等。在中间件设计中,我们需要选择合适的模型,例如洋葱模型等。

路由设计负责将客户端请求映射到特定的处理程序,并且需要考虑到URL结构、参数传递和错误处理等因素。使用前缀匹配树会使设计更加简便。

协议层设计负责定义客户端和服务器之间通信的规则,并且需要考虑到安全性、可靠性和效率等因素。在协议层设计中,我们需要抽象出合适的接口并且要确保它能够有效地传输数据。

网络层设计负责处理网络连接,并且需要考虑到网络拓扑、带宽和延迟等因素。我们需要选择合适的网络模型。