HTTP修炼之道 | 青训营笔记

73 阅读3分钟

课程背景

HTTP协议是什么

定义

HTTP: 超文本传输协议(Hypertext Transfer Protocol),包括文本、音频、视频等

为什么需要协议
  • 需要明确边界:开始结束
  • 能够携带什么信息:什么消息、消息类型、消息主体等
一个常见的POST请求到底做了什么?
  • 发送
  • 接收
HTTP协议中有什么
  • 请求行/状态行 包括方法名,URL, 协议版本等,
  • 请求头/响应头
  • 请求体/响应体
请求流程

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

分层设计

应用层设计
  • 提供合理的API:可理解性、简单性、冗余性、兼容性、可测性、可见性
中间件设计
  • 中间件需求 配合Handler实现一个完整的请求处理声明周期 拥有预处理逻辑和后处理逻辑 可以注册多中间件 对上层模块用户逻辑模块易用
  • 洋葱模型 适用场景:日志记录、性能统计、安全控制、事务处理、异常处理
  • 中间件调用链
路由设计
框架路由实际上就是为了URL匹配相应的处理函数(Handlers)
  • 静态路由: /a/b/c、/a/b/d
  • 参数路由: /a/:id/c
  • 路由修复: /a/b<->/a/b/
  • 冲突路由及优先级
  • 匹配HTTP方法
  • 多处理函数:方便添加中间件
如何匹配HTTP方法

使用路由映射表处理,如下 外层的MAP:根据method进行初步筛选

如何实现添加多处理函数处理

每个节点上使用一个list存储handler

如何做设计
  1. 明确需求
  2. 业界调研
  3. 方案权衡
  4. 方案评审
  5. 确定开发

协议层设计

  • 抽象出合适的接口
  • 需要在连接上读写数据

网络层设计

  • BIO(Blocked IO):阻塞IO,
  • NIO : 非阻塞IO

性能优化

网络库方面的优化

go net
  • 存下全部Header
  • 减少系统调用次数
  • 能够复用内存
  • 能够多次读
netpoll
  • 存下全部Header
  • 拷贝出完整的Body
  • 分配足够大的buffer
  • 限制最大buffer size
不同网络库优势
  • go net流式友好,小包性能高
  • netpoll中大包性能高,时延低

针对协议的优化-Headers解析

找到Header Line 边界: \r\n SIMD加速查找,即一次解析多个

针对协议相关的Header快速解析:
  1. 通过Header key首字母快速剔除完全不可能的key
  2. 解析对应value到独立字段
  3. 使用byte slice管理header存储,方便复用
Header解析
  • 取:核心字段快速解析,使用byte slice存储,额外存储到成员变量中
  • 舍:普通header性能较低,没有map结构
热点资源池化

使用一个RequestContext池,可以减少GC 优点是减少了内存分配,提高了内存复用,见底了GC压力,性能提升 缺点是额外的Reset逻辑

总结

本节课主要内容是HTTP协议内容与HTTP框架。首先是介绍HTTP协议的相关内容,比如说字段、协议构成,协议分层等,然后介绍了如何分层设计一个HTTP框架,以及每个分层中的具体设计思想,最后介绍了一些HTTP框架常见的优化手段。