- HTTP(Hypertext Transfer Protocol) 超文本协议
- 方法名 URL 协议---版本请求行/状态行---协议版本 状态码 状态码描述
- 请求头/相应头
- 请求体/响应体
- HTTP1 基于TCP
- 队头阻塞
- 传输效率低
- 明文传输不安全
- HTTP2 TCP TLS
- 多路复用
- 头部压缩
- 二进制协议
- QUIC 基于UDP
- 解决队头阻塞
- 加密减少握手次数
- 支持快速启动
- HTTP分层设计 --就是研究常用的HTTP库的设计,如何设计HTTP框架
- 分层设计的优势 高内聚 低耦合 易复用 高扩展性
- 应用层设计
- 提供合理的API 可理解性 简单性
- 中间件设计 --洋葱模型
- 配合Handle实现一个完整的请求处理生命周期
- 拥有预处理和后处理逻辑
- 可以注册多个中间件
- 对上层模块用户逻辑模块易用
- 路由设计 实际上就是为URL匹配对应的处理函数(Handlers)
- 静态路由 绝对地址 /a/b/c
- 参数路由 /a/:id/c---> 可以匹配 /a/b/c /a/任意id/c /*all
- 路由修复 /a/b ------/a/b/ 自动补偿斜杠
- 冲突路由以及优先级 /a/b /:id/c 到底匹配哪个??
- 匹配HTTP方法 GET POST等
- 多处理函数 方便添加中间件
- 如何匹配路由
- 青铜:map[string]handlers 只能解决静态路由
- 黄金: 前缀匹配树 解决参数路由
- 如何匹配HRTTP方法 使用MAP(方法为键,值为路由树)
- 多处理函数可以使用list
- 协议层设计
- golang推荐编程,不要把上下文(context)写进结构体,而是传参
- 需要在连接上读写数据,返回ERROR
- 网络层设计
- BIO(类似于八小时里的服务器交互设定,读的过程是阻塞的) NIO(先监听读,有足够数据再进行go协程处理业务逻辑)
- BIO Read(b []byte)(n int,err error) Write同理
- NIO Read 先peek看有没有这么多 Write写入缓冲区,调用Flush刷新
- 性能修炼之道
- 针对网络库的优化
- buffer设计:创建一个足够大的buffer 采用无锁化 多个节点的链表
- 存下全部的Header 减少系统调用次数 能够复用内存 能够多次读
- 针对协议的优化
- Headers解析 每次需要找到边界结束 \r\n
- 直接找\n看前一个是不是\r 没必要用KMP等算法
- SIMD(Single Instruction Multiple Data)即单指令流多数据流 Sonic(字节开源的加速库) 使用SIMD加速查找 快20倍左右
- 加速特定Header的取用
- 热点资源池化 减少GC sync.Pool
- Headers解析 每次需要找到边界结束 \r\n
- 针对网络库的优化
- 企业实践--追求的目标
- 追求性能(不盲目)
- 追求易用,减少误用
- 打通内部生态--trace metrics
- 文档建设,用户群建设
- 字节内部HTTP框架Hertz
- 作业
- 为什么HTTP框架要做分层设计?分层设计有哪些优势和劣势?
保证代码的可维护性,可读性,可复用性和模块化,每个层次都为其上一层提供服务。 模块化 可以解耦 可维护性和可读性 代码复用 灵活性也就是可扩展 劣势:性能开销 设计和开发难度 设计不好可能会增加复杂性
- 现有开源社区HTTP框架有哪些优势和不足
优势:成熟稳定 丰富的功能 易于使用 劣势:有一定的学习曲线,过度抽象,不适合所有场景
- 中间件有哪些实现方式?可以用伪代码说明(待学习)
- 完成基于路由前缀树的注册与查找功能,可以用伪代码说明 (待学习)
- 路由注册还有没有其他的实现方式
使用哈希表?正则表达式?