主要处理根据路由选择对应的后端逻辑。
再谈http协议
http协议是什么?
HTTP:超文本传输协议(Hypertext Transfer Protocol)
为什么需要协议?
按照一定的规则让对方理解我们传输的信息,我们需要明确的边界,能够携带什么样的信息。
协议里有什么
拿常见的post请求举例
协议中post开头,接上我们的url,在接上我们的http版本,这就是请求行。
接下来的四行都是kv对,这是我们的源数据。其中有Content-Lenght表示额传输的数据的字节数。
最后是我们真正想说的话。
回复部分,有http版本,状态码,对状态码的描述,源数据,传输的内容
请求行,状态行
方法名(get,post,head,put,delete,connect,options,trace,patch),url,协议版本
状态码:1XX(信息类),2XX(成功),3XX(重定向),4XX(客户端错误),5XX(服务端错误)
请求头,响应头
包括协议相关和业务相关
请求体,响应体
一个Demo(postman软件)
不要尝试go get这些包,这是自己开发的包,也是我们学习的重点(笔者在这里犯迷糊了)
请求流程
首先在业务层,再进入服务治理逻辑依托于中间件层,路由层,协议编(解)码层,传输层
不足与展望
- Http1:队头阻塞,传输效率低,明文传输不安全
- Http2:多路复用,头部压缩,二进制协议
- QUIC:基于UDP实现,解决队头阻塞,加密减少握手次数,支持快速启动
HTTP框架的设计与实现
分层设计
- 高内聚,低耦合
- 易复用
- 高扩展性
应用层:跟用户打交道
中间件层:对用户有一些预处理逻辑
路由层:原生的路由寻址
协议层:支持协议,实现对应的抽象接口
网络层:灵活替换网络库的逻辑
应用层
提供合理的API
- 可理解性:如ctx.Body() ctx.GetBody() 不要用ctx.BodyA()
- 简单性:如ctx.Request.Header.Peek(key) /ctx.GetHeader(key)
- 冗余性:不要出现几个接口做同样的事情
- 兼容性
- 可测性
- 可见性
中间件层
- 配合Handler实现一个完整的请求处理生命周期
- 拥有预处理逻辑与后处理逻辑
- 可以注册多中间件
- 对上层模块用于逻辑模块易用
路由设计
- 框架路由实际上就是为url匹配对应的处理函数
- 静态路由/a/b/c,/a/b/d
- 参数路由/a/:id/c,(/a/b/c,/a/b/c),/*all
- 路由修复/a/b <-> /a/b/\
- 冲突路由以及优先级/a/b,/:id/c
- 匹配http方法
- 多处理函数:方便添加中间件
如果要设计一个路由:
青铜:map[string]handlers
黄金:前缀匹配树
如何匹配http方法?
如何实现添加多处理函数?
在每个节点上使用一个list存储handler
如何查找路由?
协议层
抽象出合适的接口
传输层
BIO(阻塞io)
例如:客服打电话问你要身份证,你找身份证时,他需要一直等待
NIO
注册一个监听器
修能修炼之道
针对网络库的优化
go net "BIO"
存下全部的header,减少系统调用次数,能够复用内存,能够多次读。
go net with bufio
绑定一块缓冲区