这是我参与「第五届青训营」伴学笔记创作活动的第 9 天
本节课主要介绍:
一、再谈 HTTP 协议
1.2协议里有什么
常见方法名:GET,HEAD,POST,PUT,DELETE,CONNECT,OPTIONS,TRACE,PATCH
状态码:
1xx: 信息类
2xx: 成功
3xx: 重定向
4xx: 客户端错误
5xx= 服务端错误
1.3请求流程
1.4不足与展望
HTTP1:
队头阻塞 传输效率低 明文传输不安全
HTTP2:
多路复用 头部压缩 二进制协议
QUIC: 基于UDP实现 解决队头阻塞 加密减少握手次数 支持快速启动
二、HTTP框架的设计与实现
2.1分层设计
专注性
扩展性
复用性
高内聚 ;低耦合
易复用
高扩展性
2.2应用层设计
提供合理的API
1.可理解性:如ctx.Body(),ctx.GetBody(),不要用ctx.BodyA()
2.简单性:如ctx.Request.Header.Peek(key)/ctx.GetHeader (key)
3.冗余性
4.兼容性
5.可测性
6.可见性
2.3中间件设计
中间件需求:
1.配合Handler实现一个完整的请求处理生命周期
2.拥有预处理逻辑与后处理逻辑
3.可以注册多中间件
4.对上层模块用户逻辑模块易用
洋葱模型:
适用场景:
日志记录 性能统计 安全控制 事务处理 异常处理
调用链:
适用场景:
不调用Next:
初始化逻辑且不需要
在同一调用栈
调用Next:
后处理逻辑或需要在
同一调用栈上
2.4路由设计
框架路由实际上就是为URL匹配对应的处理函数(Handlers) 1.静态路由:/a/b/c、/a/b/d
2.参数路由:/a/:id/c(/a/b/c,/a/d/c)、/*all
3.路由修复:/a/b<->/a/b/
4.冲突路由以及优先级:/a/b、/:id/c
5.匹配HTTP方法
6.多处理函数:方便添加中间件
青铜:map[string]handlers
/a/b/c、/a/b/d/a/:id/c、/*all
黄金:前缀匹配树
/a/b/c、/a/b/d
如何处理带参数的路由注册?
(处理形如:/a/:id/b类型的路由)
如何匹配HTTP方法?
2.4如何做设计
1.明确需求:考虑清楚要解决什么问题、有哪些需求
2.业界调研:业界都有哪些解决方案可供参考
3.方案权衡:思考不同方案的取舍
4.方案评审:相关同学对不同方案做评审
5.确定开发:确定最合适的方案进行开发
2.5协议层设计
抽象出合适的接口
2.6网络层设计
网络模型
三、性能修炼之道
3.1针对网络库的优化
go net:(流式友好;小包性能高)
存下全部Header
减少系统调用次数
能够复用内存
能够多次读
go net with bufio:
绑定一块缓冲区
netpoll:(中大包性能高;时延低)
存下全部Header
拷贝出完整的Body
netpol with nocopy peek:
分配足够大的buffer
限制最大buffer size
3.2针对协议的优化一Headers
针对协议相关的Headers快速解析:
1.通过Header key首字母快速筛除掉完全不可能的key
2.解析对应value到独立字段
3.使用byte slice管理对应header存储,方便复用
请求体中同样处理的Key:
User-Agent、Content-Type、Content-Length、Connection、Transfer-Encoding
3.4热点资源池化
取:
1.减少了内存分配 2.提高了内存复用 3.降低了GC压力 4.性能提升
舍:
1.额外的Reset逻辑 2.请求内有效 3.问题定位难度增加
四、企业实践
追求性能
追求易用,减少误用
打通内部生态
文档建设、用户群建设
引用: 字节内部课-走进 HTTP 协议 - 掘金 (juejin.cn)