HTTP框架设计 | 青训营

71 阅读3分钟
  1. HTTP(Hypertext Transfer Protocol) 超文本协议
    • 方法名 URL 协议---版本请求行/状态行---协议版本 状态码 状态码描述
    • 请求头/相应头
    • 请求体/响应体
    • HTTP1 基于TCP
      • 队头阻塞
      • 传输效率低
      • 明文传输不安全
    • HTTP2 TCP TLS
      • 多路复用
      • 头部压缩
      • 二进制协议
    • QUIC 基于UDP
      • 解决队头阻塞
      • 加密减少握手次数
      • 支持快速启动
  2. HTTP分层设计 --就是研究常用的HTTP库的设计,如何设计HTTP框架
    • 分层设计的优势 高内聚 低耦合 易复用 高扩展性
    • 应用层设计
      • 提供合理的API 可理解性 简单性
    • 中间件设计 --洋葱模型
      • 配合Handle实现一个完整的请求处理生命周期
      • 拥有预处理和后处理逻辑
      • 可以注册多个中间件
      • 对上层模块用户逻辑模块易用
    • 路由设计 实际上就是为URL匹配对应的处理函数(Handlers)
      • 静态路由 绝对地址 /a/b/c
      • 参数路由 /a/:id/c---> 可以匹配 /a/b/c /a/任意id/c /*all
      • 路由修复 /a/b ------/a/b/ 自动补偿斜杠
      • 冲突路由以及优先级 /a/b /:id/c 到底匹配哪个??
      • 匹配HTTP方法 GET POST等
      • 多处理函数 方便添加中间件
      • 如何匹配路由
        • 青铜:map[string]handlers 只能解决静态路由
        • 黄金: 前缀匹配树 解决参数路由
      • 如何匹配HRTTP方法 使用MAP(方法为键,值为路由树)
      • 多处理函数可以使用list
    • 协议层设计
      • golang推荐编程,不要把上下文(context)写进结构体,而是传参
      • 需要在连接上读写数据,返回ERROR
    • 网络层设计
      • BIO(类似于八小时里的服务器交互设定,读的过程是阻塞的) NIO(先监听读,有足够数据再进行go协程处理业务逻辑)
      • BIO Read(b []byte)(n int,err error) Write同理
      • NIO Read 先peek看有没有这么多 Write写入缓冲区,调用Flush刷新
  3. 性能修炼之道
    • 针对网络库的优化
      • buffer设计:创建一个足够大的buffer 采用无锁化 多个节点的链表
      • 存下全部的Header 减少系统调用次数 能够复用内存 能够多次读
    • 针对协议的优化
      • Headers解析 每次需要找到边界结束 \r\n
        • 直接找\n看前一个是不是\r 没必要用KMP等算法
        • SIMD(Single Instruction Multiple Data)即单指令流多数据流 Sonic(字节开源的加速库) 使用SIMD加速查找 快20倍左右
        • 加速特定Header的取用
      • 热点资源池化 减少GC sync.Pool
  4. 企业实践--追求的目标
    • 追求性能(不盲目)
    • 追求易用,减少误用
    • 打通内部生态--trace metrics
    • 文档建设,用户群建设
    • 字节内部HTTP框架Hertz
  5. 作业
    • 为什么HTTP框架要做分层设计?分层设计有哪些优势和劣势?

    保证代码的可维护性,可读性,可复用性和模块化,每个层次都为其上一层提供服务。 模块化 可以解耦 可维护性和可读性 代码复用 灵活性也就是可扩展 劣势:性能开销 设计和开发难度 设计不好可能会增加复杂性

    • 现有开源社区HTTP框架有哪些优势和不足

    优势:成熟稳定 丰富的功能 易于使用 劣势:有一定的学习曲线,过度抽象,不适合所有场景

    • 中间件有哪些实现方式?可以用伪代码说明(待学习)
    • 完成基于路由前缀树的注册与查找功能,可以用伪代码说明 (待学习)
    • 路由注册还有没有其他的实现方式

    使用哈希表?正则表达式?