一.HTTP协议
1.HTTP协议是什么
HTTP:超文本传输协议(Hypertext Transfer Protocol)
- 需要明确的边界:开始和结束
- 能够携带信息:什么信息、消息类型
2.协议里有什么
请求行:包含方法名、URL、协议版本
常见方法名:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH
状态行:包含协议版本、状态码、状态码描述
状态码:
1xx:信息类 2xx:成功 3xx:重定向 4xx:客户端错误 5xx:服务端错误
3.请求流程
4.不足与展望
HTTP1:基于TCP实现
不足:
- 队头阻塞
- 传输效率低
- 不支持多路复用
- 明文传输不安全
HTTP2:
- 支持多路复用
- 可以头部压缩,对重复的信息缓存
- HTTP2是一个二进制协议,解析高效
QUIC:基于UDP实现
- 解决队头阻塞
- 加密减少握手次数
- 支持快速启动
二.HTTP框架的设计与实现
1.分层设计
专注性、扩展性、复用性
应该考虑到:高内聚、低耦合;易复用;高扩展性
2.应用层设计
核心:提供合理的API
- 可理解性:如ctx.Body(),ctx.GetBody()
- 简单性:如ctx.GetHeader(key)
- 冗余性
- 兼容性
- 可测性
- 可见性
3.中间件设计
需求:
- 配合Handler实现一个完整的请求处理生命周期
- 拥有预处理逻辑与后处理逻辑
- 可以注册多中间件
- 对上层模块用户逻辑模块易用
适用场景:日志记录、性能统计、安全控制、事务处理、异常处理
4.路由设计
框架路由实际上就是为URL匹配对应的处理函数(Handlers)
- 静态路由:/a/b/c、/a/b/d
- 参数路由:/a/:id/c (/a/b/c,/a/d/c)、/*all
- 路由修复:/a/b <=> /a/b/
- 冲突路由以及优先级:/a/b、/:id/c
- 匹配HTTP方法
- 多处理函数:方便添加中间件
如何匹配HTTP方法?
外层Map:根据method进行初步筛选
如何实现添加多处理函数?
在每个节点上使用一个list存储handler
如何做设计?
- 明确需求:考虑清楚要解决什么问题、有哪些需求
- 业界调研:业界都有哪些解决方案可供参考
- 方案权衡:思考不同方案的取舍
- 方案评审:相关同学对不同方案做评审
- 确定开发:确定最合适的方案进行开发
5.协议层设计
核心:抽象出合适的接口
6.网络层设计(网络模型)
BIO:阻塞io
go net 由用户管理buffer
NIO:
netpoll 由网络库管理buffer
netpoll地址:github.com/cloudwego/n…
三.性能修炼之道
1.针对网络库的优化
go net 需求:
存在全部Header
减少系统调用次数
能够复用内存
能够多次读
解决方法:绑定一块大小为4KB的缓冲区
netpoll:由链表实现
需要存下全部Header,拷贝出完整的Body
解决方案:在底层分配足够大的buffer,限制最大buffer size
- go net 优势:对流式友好、小包性能高
- netpoll 优势:中大包性能高、时延低
2.针对协议的优化
主要对Headers解析
找到Header Line 边界:\r\n, 来判断完整性
先找到 \n 再看它前一个是不是 \r
func index(b []byte, c byte) int {
for i := 0; i < len(b); i++ {
if b[i] == c {
return i
}
}
return -1
}
针对协议相关的Headers快速解析:
通过Header key 首字母快速筛除掉完全不可能的key
解析对应 value 到独立字段
使用 byte slice 管理对应 header 存储,方便复用
请求体中同样处理的Key:
User-Agent、Content-Type、Content-Length、Connection、Transfer-Encoding
3.热点资源池化
与请求一一对应,贯穿一个请求始终
优点:
- 减少了内存分配
- 提高了内存复用
- 降低了GC压力
- 性能提升
缺点:
- 额外的Reset逻辑
- 请求内有效
- 问题定位难度增加
四.总结
本节课深入理解了HTTP协议的工作原理,包括请求和响应的结构、状态码、方法、头信息,掌握HTTP/1.1和HTTP/2的区别,以及它们在性能和功能上的改进。通过学习路由和中间件等相关知识,了解如何设计清晰且高效的路由系统,以及如何使用中间件来处理夸请求的逻辑,掌握路由参数的提取和使用。最后,了解如何优化HTTP请求的性能,包括使用缓存、连接池等技术,学习如何分析和优化应用程序的性能瓶颈,提高吞吐量和响应速度。
在企业开发中应该追求性能、追求易用减少误用、打通内部生态、文档建设用户群建设。