课程背景
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
如何做设计
- 明确需求
- 业界调研
- 方案权衡
- 方案评审
- 确定开发
协议层设计
- 抽象出合适的接口
- 需要在连接上读写数据
网络层设计
- 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快速解析:
- 通过Header key首字母快速剔除完全不可能的key
- 解析对应value到独立字段
- 使用byte slice管理header存储,方便复用
Header解析
- 取:核心字段快速解析,使用byte slice存储,额外存储到成员变量中
- 舍:普通header性能较低,没有map结构
热点资源池化
使用一个RequestContext池,可以减少GC 优点是减少了内存分配,提高了内存复用,见底了GC压力,性能提升 缺点是额外的Reset逻辑
总结
本节课主要内容是HTTP协议内容与HTTP框架。首先是介绍HTTP协议的相关内容,比如说字段、协议构成,协议分层等,然后介绍了如何分层设计一个HTTP框架,以及每个分层中的具体设计思想,最后介绍了一些HTTP框架常见的优化手段。