HTTP,超文本传输协议(Hypertext Transfer Protocol),超在哪?超在支持传输各种类型的数据,图片、视频、超链接等。
协议组成
POST /api/data HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
请求行/状态行
POST /xxx HTTP/1.1
Method:表示HTTP请求的方法或动作,通常是大写字母,例如GET、POST、PUT、DELETE等。不同的方法代表着不同的请求行为。Request-URI:表示请求的目标资源标识符(Uniform Resource Identifier),即请求的URL或路径。例如:/index.html、**/api/data**等。HTTP-Version:表示HTTP协议的版本。目前常见的版本有HTTP/1.0和HTTP/1.1。
请求头/响应头
HTTP请求头(HTTP Request Headers)是HTTP请求中的一组字段,用于向服务器传递额外的信息和参数。请求头包含在HTTP请求的头部,位于请求行之后,每个字段由键值对组成,键和值之间用冒号分隔,每个字段以换行符(CRLF,Carriage Return Line Feed)分隔(因为每个OS中对换行的定义都不同,有\n,有\r\n) 。
常见的HTTP请求头字段包括:
User-Agent:用于标识发送请求的客户端应用程序或用户代理的信息。Host:指定目标服务器的主机名和端口号。Accept:指定客户端可以处理的媒体类型(MIME类型)。Content-Type:用于指定请求主体的MIME类型,表示请求中包含的数据类型。Content-Length:指定请求主体的长度,通常用于POST请求。Authorization:用于在请求中传递身份验证信息,例如基本身份验证或令牌。Referer:指定当前请求的来源URL,常用于记录页面跳转来源。Cookie:包含由服务器发送的cookie信息,用于向服务器发送存储在客户端的cookie数据。If-Modified-Since:用于条件性GET请求,表示只有在指定时间之后有修改时才会返回资源。Cache-Control:用于控制缓存的行为,例如指定缓存策略或禁止缓存。Origin:指定请求的来源,用于跨域请求时的安全检查。X-Requested-With:用于指示异步请求的来源,常用于判断是否是AJAX请求。- …
请求体
在HTTP请求中,请求体的存在与否取决于请求的类型和需要传递的数据。对于GET请求,通常不包含请求体,因为GET请求的参数会通过URL的查询字符串来传递。而对于POST、PUT等请求,请求体可以用来传递更大量的数据或复杂的数据结构,通常会包含在请求中。
请求体的格式和内容由请求头中的**Content-Type**字段来指定,它表示请求体中数据的媒体类型(MIME类型)。
不足和展望
HTTP1: 队头阻塞、传输效率低、明文传输不安全
HTTP2: 多路复用、头部压缩、二进制协议
QUIC: 基于UDP、解决队头阻塞、加密解决握手次数、支持快速启动
设计HTTP框架
网路分层设计介绍——OSI
运用中间件设计——洋葱模型
Better:
- 外层:日志中间件
- 中层:Metrics中间件
- 内层:Biz、Handler。
请求由外向内,响应由内向外
路由设计
- 静态路由
- 动态路由
- 路由修复
- RestFul API规范实现
- 多处理函数(multi-handler)
可用前缀匹配树(map只适用于静态路由)来匹配路由。
协议层设计
- 有error要及时抛出
网络层设计
- BIO:阻塞IO。在接收数据时,阻塞。
- NIO:非阻塞IO。可用goroutine。如在接收数据时,用Monitor来监听,不阻塞。
golang的net包用的是BIO,需要用户管理buffer。字节的netpoll用的是NIO,内部管理buffer。
优化
Headers解析
- 先找到\n,再找\r。
- 通过Header key的首字母快速筛选掉完全不可能的key
- 解析value到独立字段
- 可以使用byte slice管理header存储,方便复用。
Header key规范化
对大小写转换(user-key → User-Key)用表映射(打表)。
热点资源池化
就是缓存热点资源。
- 追求性能
- 追求易用,减少误用
- 文档建设、用户群建设。
Q/A
HTTP框架为什么要分层设计?优势和劣势?
为了提高代码的可维护性、可扩展性和代码的重用性。分层设计可以将不同的功能模块划分为独立的层,每个层都专注于特定的任务,使得整个框架更加模块化和易于管理、可扩展性高。**劣势:**分层设计可能引入一些额外的开销,因为不同层之间的通信可能需要序列化、反序列化等操作
中间件实现方式?
- 洋葱模型。
- 基于条件的洋葱模型。
- 装饰器模式。类似于python函数的装饰器。可想而知,这样可以支持更加高细粒度的业务。
- AOP。