HTTP框架修炼之道 | 青训营笔记

111 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 9 天

本节课主要介绍:

一、再谈 HTTP 协议

1.2协议里有什么

常见方法名:GET,HEAD,POST,PUT,DELETE,CONNECT,OPTIONS,TRACE,PATCH

状态码:

1xx: 信息类

2xx: 成功

3xx: 重定向

4xx: 客户端错误

5xx= 服务端错误

image.png

1.3请求流程

image.png

1.4不足与展望

HTTP1:

队头阻塞 传输效率低 明文传输不安全

HTTP2:

多路复用 头部压缩 二进制协议

QUIC: 基于UDP实现 解决队头阻塞 加密减少握手次数 支持快速启动

二、HTTP框架的设计与实现

2.1分层设计

专注性

扩展性

复用性

image.png

高内聚 ;低耦合

易复用

高扩展性

image.png

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.对上层模块用户逻辑模块易用

洋葱模型:

适用场景:

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

调用链:

image.png

适用场景:

不调用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.多处理函数:方便添加中间件

image.png 青铜:map[string]handlers

/a/b/c、/a/b/d/a/:id/c、/*all

黄金:前缀匹配树

/a/b/c、/a/b/d

如何处理带参数的路由注册?

(处理形如:/a/:id/b类型的路由)

如何匹配HTTP方法?

image.png

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)