Go语言HTTP框架设计 | 青训营

77 阅读3分钟

HTTP协议

HTTP:超文本传输协议 (Hypertext Transfer Protocol)

image.png

协议结构

协议开始

协议元数据

Text

协议结束

协议里有什么

image.png

请求流程

image.png

缺点不足

HTTP1

队头阻塞

传输效率低

明文传输不安全

HTTP2

多路复用

头部压缩

二进制协议

QUIC

基于UDP实现

解决队头阻塞

加密减少握手次数

支持快速启动

分层设计

专注性

扩展性

复用性

image.png

高内聚 低耦合

易复用

高扩展性

image.png

image.png

image.png

应用层设计

提供合理的 API

冗余性

兼容性

可测性

可见性

中间件设计

中间件需求

配合 Handler 实现一个完整的请求处理生命周期

拥有预处理逻辑与后处理逻辑

可以注册多中间件

对上层模块用户逻辑模块易用

洋葱模型

image.png

1、既然要实现预处理和后处理,那这个就很像调用了一个函数

2、路由上可以注册多 Middleware,同时也可以满足请求级别有效只需要将 Middleware 设计为和业务和 Handler 相同即可。

3、用户如果不主动调用下一个处理函数怎么办?

  • 核心:在任何场景下index保证递增

4、出现异常

  • 调用链:

image.png

适用场景:

不调用 Next:初始化逻辑且不需要在同一调用栈

调用 Next:后处理逻辑或需要在同一调用栈上

路由设计

框架路由实际上就是为 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、多处理函数:方便添加中间件

解决方案

1、map[string]handlers

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

2、前缀匹配树

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

image.png

设计案例

/a/b/c

/a/b/d

/a/:b/d

/a/:c/f

image.png

匹配HTTP

外层 Map; 根据 method 进行初步筛选

image.png

实现添加多处理函数

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

设计

1、明确需求: 考虑清楚要解决什么问题、有哪些需求

2、业界调研:业界都有哪些解决方案可供参考

3、方案权衡:思考不同方案的取舍

4、方案评审: 相关同学对不同方案做评审

5、确定开发:确定最合适的方案进行开发

协议层设计

1、不要将上下文存储在结构类型内;相反,将Context显式传递给每个需要它的函数。Context应该是第一个参数。

2、需要在连接上读写数据

网络层设计

BIO

go net

用户管理 buffer

NIO

net poll

网络库管理 buffer

总结

1、API设计:可理解性、简单性

2、中间件设计:洋葱模型

3、路由设计:前缀匹配树

4、协议层设计: 抽象出合适的接口

5、网络层设计: 网络模型

网络库的优化

go net

存下全部 Header减少系统调用次数能够复用内存能够多次读

go net with bufio

绑定一块缓冲区

net poll

存下全部 Header拷贝出完整的 Body

image.png

net poll with nocopy peek

分配足够大的 buffer

限制最大 buffer size

image.png

优势

go net

流式友好

小包性能高

net poll

中大包性能高

时延低

协议优化

Headers 解析

找到 Header Line 边界:\r \n

先找到\n 再看它前一个是不是 \r

针对协议相关的 Headers 快速解析:

1、通过 Header key 首字母快速筛除掉完全不可能的 key

2、解析对应 value 到独立字段

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

请求体中同样处理的Key:User-Agent、Content-Type、 Content-Length、Connection、 Transfer-Encoding

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

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

额外的内存开销变更困难

热点资源池化

image.png

image.png