HTTP框架介绍 | 笔记

142 阅读5分钟

HTTP介绍

  • 前后端通过http进行通信

    • 下面是一张前后端分离的流程图

      !

HTTP协议

  • HTTP:超文本传输协议

    • 需要明确的开始与结束的边界

    • 能够携带信息:文本、图片、音频视频等

    • 请求由请求行+请求头+请求体组成

    • 响应由响应行+响应头+响应体组成

    • 常见的请求方法:

      • GET: 请求一个指定资源的表示形式,使用 GET 的请求应该只被用于获取数据。
      • HEAD: 请求一个与 GET 请求的响应相同的响应,但没有响应体。
      • POST: 用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
      • PUT: 用请求有效载荷替换目标资源的所有当前表示。
      • DELETE: 删除指定的资源。
      • CONNECT: 建立一个到由目标资源标识的服务器的隧道。
      • OPTIONS: 用于描述目标资源的通信选项。
    • 常见的状态码

      状态码类别描述
      1xxInformational(信息状态码)接受请求正在处理
      2xxSuccess(成功状态码)请求正常处理完毕
      3xxRedirection(重定向状态码)需要附加操作已完成请求
      4xxClient Error(客户端错误状态码)服务器无法处理请求
      5xxServer Error(服务器错误状态码)服务器处理请求出错

      作者:青颜的天空 链接:juejin.cn/post/684490…

  • 请求流程

HTTP框架的设计与实现

分层设计

image.png

image.png

  • 与前面对比

    image.png

应用层(API)设计

  • 提供合理的API

    • 可理解性
    • 简单性
    • 冗余性
    • 兼容性
    • 可测性
    • 可见性

中间件设计(Middleware)

  • 中间件:又译中间件、中介层,是一类提供系统软件和应用软件之间连接、便于软件各部件之间的沟通的软件,应用软件可以借助中间件在不同的技术架构之间共享信息与资源。中间件位于客户机服务器的操作系统之上,管理着计算资源和网络通信。

  • 好的中间件设计:

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

    • 核心逻辑与通用逻辑分离

    • 适用场景:

      • 日志记录、性能统计、安全控制、事务处理、异常处理

路由层设计

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

  • 路由层需要的功能

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

    • map[string]handlers(键值对):只适用于静态路由
    • 前缀匹配树
  • 匹配HTTP方法 - 路由映射表:

协议层设计

抽象出合适的接口

网络层设计

  • BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
  • NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  • AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

如何做设计

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

框架优化

网络库优化

  • go net

    • 存下所有Header
    • 减少系统调用次数
    • 能够复用内存
    • 能过够多次读取
  • netpoll

    • 存下所有Header
    • 拷贝出完整的Body
  • 不同网络库的优势

    • go net : 流式友好,小包性能高
    • netpoll:中大包性能高,时延低
  • 总结:关键是buffer设计

针对协议优化

  • Headers解析

    • 通过Header Key首字母快速筛选掉完全不可能的key

    • 解析对应value到独立字段

    • 使用byte slice管理对应header储存,方便复用

    • 优点

      • 核心字段快速解析
      • byte slice储存
      • 额外储存到成员变量中
    • 缺点

      • 普通header性能较低
      • 没有map结构
  • Header key规范化

    • 优点

      • 超高的转换效率
      • 比net.http提高40倍
    • 缺点

      • 额外的内存开销
      • 变更困难
  • 热点资源池化

    • 正常情况下

      • RequestContext 与请求一一对应,贯穿一个请求始终,高并发时压力太大

    • 池化后

      • 请求来的时候,从池子中取出 RequestContext

      • 处理完后将 RequestContext 放回池子里下个请求可以复用,

    • 优点

      • 减少内存分配
      • 提高内存复用
      • 降低 GC 压力
      • 性能提升
    • 缺点

      • 额外的 Reset 逻辑
      • 请求内有效
      • 问题定位难度增加