http协议在计算机网络中具有重要的地位,在我们的项目部署服务的时候也可能会用到。因为我们的工程终将面向客户,而走向客户的方式就在于网络。
什么是http协议?
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应(选自百度百科)。
这是什么意思?
意思就是,如果把传递的信息作为一种对象,那么http协议就规定了它的属性,这些属性可能有默认值,也可能没有。但在确定了属性之后,客户端、服务端就可以通过解析对应的属性进行操作。
http协议里面有什么?
请求协议
请求行
我在CSDN(blog.csdn.net/weixin_5293… 上找到了一篇讲述较为清晰的文章,感兴趣的可以参考:
- 请求的方式
- url
- HTTP协议的版本号
请求头
用于告诉服务器如何处理请求和发送响应。
请求体、响应体
浏览器向服务端发送的具体数据。
响应协议
状态行
包含有:
- 版本号
- 状态码
- 状态的描述信息:是否成功响应或者在什么地方出现了报错
响应头
包含:
- 内容类型
- 内容大小
- 响应时间
- ……
响应体
一个长字符串,服务器响应给浏览器的正文,被浏览器解析渲染,解释并执行,最终展示出效果。
请求流程
如图所示:
此处为计算机网络相关内容(三次握手等),不作赘述,详情可以参考此处。
http框架的设计与实现
分层设计
图片源自百度
http协议是应用层协议,拥有:- 专注性
- 扩展性
- 复用性
- 高内聚、低耦合
同时,http协议需要经过其它几层才能够传输到服务端。
应用层设计
我们需要提供合理的接口:
- 可理解
- 简单
- 兼容
- 可测
- 可见
这是什么意思呢?
- 从命名开始,我们就要起让人一目了然的名字;
- 我们需要用最少的接口完成最多的事情:能用一个接口完成的任务不用两个,能用已有的两个接口拼接出来的功能不用新增接口。
- 接口功能可测试、并且清晰明了。
- 接口要有好的兼容性。
中间件设计
需求:
- 配合handler实现一个完整的生命周期
- 拥有预处理与后处理逻辑
- 可以注册多中间件
- 对上层模块、用户逻辑模块易用
可以参考洋葱模型:
既然要实现后处理和预处理,那么就很像是要写一个函数,只需要调用就可以了。
但如果用户不主动调用下一个处理函数怎么办?
不知道大家有没有联想到计算机组成原理当中的pc指针,永远在递增,向机器中输入下一条指令的地址,便于取指。这个设计和本次的设计有异曲同工之妙。 我们只要在任何场景下保证index递增即可。如果出现异常,想要停止怎么办?
可以让索引放置在无法继续递增的最大位置上。路由设计
为url匹配对应的处理函数。
写过项目的同学可能知道,我们需要url来确认调用的接口,有的会传递一个request body,有的会在url外层拼接上一个参数。
那么,每一个url的节点都可能会往下延伸出更多的节点,这是一种什么样的数据结构?
树!
接着,我们确认了数据结构,便要进行树节点的设计了。这个节点里需要含有map,method,前缀树和头结点。
协议层设计
抽象合适的接口。
网络层设计
用户管理、网络库管理……
需要用到网络模型!
做设计的方式
- 明确需求
- 业界调研
- 方案权衡
- 方案评审
- 方案开发
提升性能
优化网络库
- 存下全部的header,减少系统调用次数,能够复用内存
- 绑定一块缓冲区
优化协议
- 提升解析速度:快速筛选key,解析value,使用byte slice管理对应header存储,方便复用。
- 规范化key
- 热点资源池化
但是,就像是算法的时空折中原理,有得必有失。
不同网络库的优劣
| 库名 | 特点 |
|---|---|
| go net | 流式友好、小包性能高 |
| netpoll | 中大包性能高,时延低 |
优化协议的对比
| 优化方式 | 优点 | 劣势 |
|---|---|---|
| Header Key规范化 | 核心字段快速解析用byte slice存储额外存储到成员变量当中 | 普通的header性能低没有map结构 |
| header解析 | 转化效率高 | 变更困难额外开销 |
| 热点资源池化 | 减少内存分配,提高内存复用降低GC压力性能提升 | 额外的reset逻辑请求内有效问题定位难度上升 |
企业实践的要求
- 追求性能
- 追求易用,减少误用
- 打通内部生态
- 文档建设、用户群建设(但要注意,注释最好写在程序里,因为有的人不看文档)
这就是http协议的相关内容啦!谢谢阅读,欢迎讨论。